Sto cercando di generalizzare il mio hack da una risposta a un altro question.Scrittura di una funzione util di Kotlin che fornisce riferimento automatico nell'inizializzatore
Dovrebbe fornire un modo per fare riferimento a un valore che non è ancora stato costruito all'interno del suo inizializzatore (ovviamente, non direttamente, ma in lambda e espressioni oggetto).
Quello che ho in questo momento:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
val self: T by lazy {
inner ?: throw IllegalStateException("Do not use `self` until initialized.")
}
private val inner = initializer()
}
fun <T> selfReference(initializer: SelfReference<T>.() -> T): T {
return SelfReference(initializer).self
}
Funziona, si veda questo esempio:
class Holder(var x: Int = 0,
val action:() -> Unit)
val h: Holder = selfReference { Holder(0) { self.x++ } }
h.action()
h.action()
println(h.x) //2
Ma a questo punto il modo in cui initializer
riferimenti al valore costruito è self
proprietà.
E la mia domanda è: esiste un modo per riscrivere SelfReference
in modo che initializer
passi un argomento (o un destinatario) anziché utilizzare la proprietà self
? Questa domanda può essere riformulata in: esiste un modo per passare un ricevitore/argomento valutato pigramente ad una funzione o raggiungere in qualche modo questa semantica?
Quali sono gli altri modi per migliorare il codice?
UPD: Un modo possibile è passare una funzione che restituisce
self
, quindi sarebbe utilizzato come
it()
all'interno
initializer
. Sto ancora cercando altri.
Potrebbe essere possibile utilizzare una combinazione di [proprietà delegate] (https://kotlinlang.org/docs/reference/delegated-properties.html#delegated-properties), [proprietà late-inizializzate] (https://kotlinlang.org/docs/reference/properties.html#late-initialized-properties) e/o [funzioni inline] (https://kotlinlang.org/docs/reference/inline-functions.html#inline-functions) generalizzare questo.Il mio tentativo dovrebbe (credo) funzionare ma c'è un bug di compilazione Kotlin che impedisce di farlo ora (vedi https://youtrack.jetbrains.com/issue/KT-10878). – mfulton26