Menu
CoddyTech

lazy dan lateinit

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Kotlin di Coddy. Pelajaran 10 dari 57.

by lazy { ... } menunda perhitungan val hingga pertama kali dibaca, lalu mengingat hasilnya. Ini cocok untuk nilai yang membutuhkan banyak komputasi atau tidak selalu diperlukan:

class Report(val rows: List<Int>) {
    val summary: String by lazy {
        println("computing summary")
        "total ${rows.sum()}"
    }
}

Di dalam main:

val r = Report(listOf(3, 4))
println("created")
println(r.summary)
println(r.summary)

Output:

created
computing summary
total 7
total 7

Blok ini berjalan sekali: pembacaan kedua di atas menggunakan hasil yang tersimpan. Berbeda dengan getter kustom, yang berjalan pada setiap pembacaan, lazy menghitung sekali dan menyimpan hasilnya dalam cache:

class Demo {
    var reads = 0
    val viaGetter: Int
        get() { reads++; return 42 }
    val viaLazy: Int by lazy { reads++; 42 }
}

Di dalam main:

val d = Demo()
repeat(3) { d.viaGetter; d.viaLazy }
println(d.reads)

Output:

4

lateinit var mendeklarasikan property non-null yang diisi nanti, setelah konstruksi, misalnya melalui method penyiapan. Membacanya sebelum diisi akan memunculkan exception, dan ::name.isInitialized memeriksanya:

class Screen {
    lateinit var title: String

    fun load(t: String) { title = t }
    fun ready() = ::title.isInitialized
}

Di dalam main:

val s = Screen()
println(s.ready())
s.load("Home")
println(s.ready())
println(s.title)

Output:

false
true
Home

Utamakan inisialisasi biasa saat nilainya sudah diketahui ketika objek dibuat. Gunakan lazy untuk val yang mahal dihitung dan mungkin tidak diperlukan, serta gunakan lateinit hanya untuk var yang nilainya benar-benar baru tersedia nanti. lateinit tidak berfungsi dengan Int, Boolean, atau tipe primitif lainnya.

val config by lazy { loadConfig() }     // dihitung sekali saat pertama kali digunakan
lateinit var user: User                 // diberi nilai setelah pembuatan object
// lateinit var count: Int              // error: tidak diperbolehkan pada tipe primitif
challenge icon

Tantangan

Mudah

Lengkapi class Document(val text: String). Tambahkan wordCount sebagai property lazy yang menghitung jumlah kata (dipisahkan oleh spasi tunggal) dan mencatat setiap perhitungan dengan menambahkan 1 ke computations, serta lateinit var author: String dengan method credit() yang mengembalikan by Ada atau by unknown jika author belum ditetapkan.

Kode yang disediakan membaca teks, membaca wordCount tiga kali, menetapkan author jika ada baris kedua, lalu mencetak words 5, computed 1, by Ada.

Tulis kodemu di Document.kt. Main.kt berisi kode input/output yang disediakan dan tidak dapat diedit.

Coba sendiri

fun main() {
    // Kode input/output yang disediakan: biarkan apa adanya
    val input = generateSequence(::readLine).toList()
    val doc = Document(input[0])
    val reads = List(3) { doc.wordCount }
    val words = reads.first()
    if (input.size > 1) doc.author = input[1]
    println("words $words, computed ${doc.computations}, ${doc.credit()}")
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Playground Kotlin