lazy e lateinit
Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 10 di 57.
by lazy { ... } rimanda il calcolo di un val fino alla prima lettura, poi ne memorizza il risultato. È adatto a valori il cui calcolo è costoso o che non sono sempre necessari:
class Report(val rows: List<Int>) {
val summary: String by lazy {
println("computing summary")
"total ${rows.sum()}"
}
}All'interno di main:
val r = Report(listOf(3, 4))
println("created")
println(r.summary)
println(r.summary)Output:
created
computing summary
total 7
total 7Il blocco viene eseguito una sola volta: la seconda lettura qui sopra ha usato il risultato memorizzato. A differenza di un getter personalizzato, che viene eseguito a ogni lettura, lazy calcola una volta e memorizza il risultato nella cache:
class Demo {
var reads = 0
val viaGetter: Int
get() { reads++; return 42 }
val viaLazy: Int by lazy { reads++; 42 }
}All'interno di main:
val d = Demo()
repeat(3) { d.viaGetter; d.viaLazy }
println(d.reads)Output:
4lateinit var dichiara una proprietà non nullable a cui viene assegnato un valore in seguito, dopo la costruzione, per esempio tramite un metodo di configurazione. Leggerla prima che le venga assegnato un valore genera un'eccezione, mentre ::name.isInitialized verifica se è stata inizializzata:
class Screen {
lateinit var title: String
fun load(t: String) { title = t }
fun ready() = ::title.isInitialized
}All'interno di main:
val s = Screen()
println(s.ready())
s.load("Home")
println(s.ready())
println(s.title)Output:
false
true
HomePreferisci un’inizializzazione semplice quando il valore è noto al momento della costruzione. Usa lazy per un val costoso che potrebbe non essere necessario e lateinit solo per un var il cui valore arriva davvero in seguito; lateinit non funziona con Int, Boolean o altri tipi primitivi.
val config by lazy { loadConfig() } // calcolato al primo utilizzo, una sola volta
lateinit var user: User // assegnato dopo la costruzione
// lateinit var count: Int // errore: non consentito per i tipi primitiviSfida
FacileCompleta la classe Document(val text: String). Aggiungi wordCount come proprietà lazy che conta le parole (separate da spazi singoli) e registra ogni calcolo aggiungendo 1 a computations, e una lateinit var author: String con un metodo credit() che restituisce by Ada oppure by unknown quando l'autore non è stato impostato.
Il codice fornito legge il testo, legge wordCount tre volte, imposta l'autore quando è presente una seconda riga e stampa words 5, computed 1, by Ada.
Il tuo codice va in Document.kt. Main.kt contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
fun main() {
// Codice di input/output fornito: lascialo così com'è
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()}")
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiCostruttori primariBlocchi init e convalidaCostruttori secondariRiepilogo - Tessera della biblioteca4Ereditarietà
Classi aperte e sottoclassiRidefinizione dei membrisuper e costruttoriClassi astratteRiepilogo - Elenco del personale2Proprietà e incapsulamento
Accessor personalizzatiModificatori di visibilitàSetter privatilazy e lateinitRipasso - Conto bancario5Interfacce
Dichiarare le interfacceMetodi predefinitiInterfacce multipleLe interfacce come tipiRiepilogo - Metodi di pagamento8Tipi generici
Funzioni genericheClassi genericheVincoli sui tipiVarianza con in e outRiepilogo - Coda con priorità11Progetto: Gestione della biblioteca
Libri e sociPrendere in prestito i libriEsercitati da solo: Playground Kotlin