lazy und lateinit
Teil des Abschnitts Objektorientierte Programmierung der Kotlin-Journey von Coddy. Lektion 10 von 57.
by lazy { ... } verzögert die Berechnung eines val, bis es zum ersten Mal gelesen wird, und merkt sich dann das Ergebnis. Es eignet sich für Werte, deren Berechnung aufwendig ist oder die nicht immer benötigt werden:
class Report(val rows: List<Int>) {
val summary: String by lazy {
println("computing summary")
"total ${rows.sum()}"
}
}Innerhalb von main:
val r = Report(listOf(3, 4))
println("created")
println(r.summary)
println(r.summary)Ausgabe:
created
computing summary
total 7
total 7Der Block wird einmal ausgeführt: Beim zweiten Lesen oben wurde das gespeicherte Ergebnis verwendet. Anders als ein benutzerdefinierter Getter, der bei jedem Lesen ausgeführt wird, berechnet lazy den Wert einmal und speichert ihn zwischen:
class Demo {
var reads = 0
val viaGetter: Int
get() { reads++; return 42 }
val viaLazy: Int by lazy { reads++; 42 }
}Innerhalb von main:
val d = Demo()
repeat(3) { d.viaGetter; d.viaLazy }
println(d.reads)Ausgabe:
4lateinit var deklariert eine Nicht-Null-Eigenschaft, der später nach der Konstruktion, beispielsweise durch eine Einrichtungsmethode, ein Wert zugewiesen wird. Wird sie gelesen, bevor ihr ein Wert zugewiesen wurde, wird eine Ausnahme ausgelöst, und ::name.isInitialized überprüft sie:
class Screen {
lateinit var title: String
fun load(t: String) { title = t }
fun ready() = ::title.isInitialized
}Innerhalb von main:
val s = Screen()
println(s.ready())
s.load("Home")
println(s.ready())
println(s.title)Ausgabe:
false
true
HomeBevorzuge eine direkte Initialisierung, wenn der Wert bei der Erstellung bekannt ist. Verwende lazy für einen aufwendigen val, der möglicherweise nicht benötigt wird, und lateinit nur für einen var, dessen Wert tatsächlich später festgelegt wird; lateinit funktioniert nicht mit Int, Boolean oder anderen primitiven Typen.
val config by lazy { loadConfig() } // bei erster Verwendung einmal berechnet
lateinit var user: User // nach der Konstruktion zugewiesen
// lateinit var count: Int // Fehler: bei primitiven Typen nicht erlaubtAufgabe
EinfachVervollständige die Klasse Document(val text: String). Füge wordCount als lazy-Eigenschaft hinzu, die die Wörter (durch einzelne Leerzeichen getrennt) zählt und jede Berechnung registriert, indem sie computations um 1 erhöht, sowie ein lateinit var author: String mit einer Methode credit(), die by Ada zurückgibt oder by unknown, wenn der Autor noch nicht festgelegt wurde.
Der bereitgestellte Code liest den Text ein, liest wordCount dreimal, legt den Autor fest, wenn eine zweite Zeile vorhanden ist, und gibt words 5, computed 1, by Ada aus.
Dein Code gehört in Document.kt. Main.kt enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
fun main() {
// Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
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()}")
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenPrimärkonstruktoreninit-Blöcke und ValidierungSekundärkonstruktorenRückblick – Bibliotheksausweis4Vererbung
Offene Klassen und UnterklassenÜberschreiben von Membernsuper und KonstruktorenAbstrakte KlassenRückblick – Mitarbeiterverzeichnis2Eigenschaften und Kapselung
Benutzerdefinierte ZugriffsmethodenSichtbarkeitsmodifikatorenPrivate Setterlazy und lateinitWiederholung – Bankkonto5Schnittstellen
Schnittstellen deklarierenStandardmethodenMehrere SchnittstellenSchnittstellen als TypenRückblick – Zahlungsmethoden8Generics
Generische FunktionenGenerische KlassenTypbeschränkungenVarianz mit in und outRückblick – Prioritätswarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Kotlin-Playground