Menu
Coddy logo textTech

lazy ve lateinit

Coddy'nin Kotlin Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 10 / 57.

by lazy { ... }, bir val değerinin hesaplanmasını ilk kez okunana kadar erteler, ardından sonucu hatırlar. Pahalı olan veya her zaman gerekmeyen değerler için uygundur:

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

main içinde:

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

Çıktı:

created
computing summary
total 7
total 7

Blok bir kez çalışır: yukarıdaki ikinci okuma, depolanan sonucu kullandı. Her okumada çalışan özel bir getter'ın aksine, lazy bir kez hesaplar ve önbelleğe alır:

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

main içinde:

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

Çıktı:

4

lateinit var, daha sonra, örneğin bir kurulum yöntemi tarafından oluşturma işleminden sonra atanan null olmayan bir özelliği bildirir. Özelliği atanmadan önce okumak bir istisna fırlatır ve ::name.isInitialized özelliğin başlatılıp başlatılmadığını kontrol eder:

class Screen {
    lateinit var title: String

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

main içinde:

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

Çıktı:

false
true
Home

Değer oluşturma sırasında biliniyorsa basit başlatmayı tercih et. Gerekli olmayabilecek maliyetli bir val için lazy kullan; lateinit ise yalnızca değeri gerçekten daha sonra gelen bir var için kullanılmalıdır; lateinit, Int, Boolean veya diğer ilkel türlerle çalışmaz.

val config by lazy { loadConfig() }     // ilk kullanımda bir kez hesaplanır
lateinit var user: User                 // oluşturulduktan sonra atanır
// lateinit var count: Int              // hata: primitive türlerde izin verilmez
challenge icon

Görev

Kolay

Document(val text: String) sınıfını tamamlayın. Kelimeleri (tek boşluklarla ayrılmış) sayan ve her hesaplamayı computations değerine 1 ekleyerek kaydeden bir lazy özelliği olarak wordCount ekleyin; ayrıca, yazar ayarlanmadığında by Ada veya by unknown döndüren credit() metoduna sahip bir lateinit var author: String ekleyin.

Sağlanan kod metni okur, wordCount değerini üç kez okur, ikinci bir satır mevcut olduğunda yazarı ayarlar ve words 5, computed 1, by Ada yazdırır.

Kodunuz Document.kt dosyasına yazılmalıdır. Main.kt sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

fun main() {
    // Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
    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 iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Kotlin playground