Kotlin
Delegerade fastigheter
Sök…
Introduktion
Kotlin kan delegera implementeringen av en egendom till ett hanteringsobjekt. Vissa standardhandlare ingår, såsom lat initialisering eller observerbara egenskaper. Anpassade hanterare kan också skapas.
Lat initialisering
val foo : Int by lazy { 1 + 1 }
println(foo)
Exemplet skriver ut 2
.
Observera egenskaper
var foo : Int by Delegates.observable("1") { property, oldValue, newValue ->
println("${property.name} was changed from $oldValue to $newValue")
}
foo = 2
Exemplet skriver ut foo was changed from 1 to 2
Kartstödda egenskaper
val map = mapOf("foo" to 1)
val foo : String by map
println(foo)
Exemplet skriver ut 1
Anpassad delegation
class MyDelegate {
operator fun getValue(owner: Any?, property: KProperty<*>): String {
return "Delegated value"
}
}
val foo : String by MyDelegate()
println(foo)
Exemplet skriver ut Delegated value
Delegat Kan användas som ett lager för att minska pannplattan
Tänk på Kotlins Null Type-system och WeakReference<T>
.
Så låt oss säga att vi måste spara någon form av referens och vi ville undvika minnesläckor, här är där WeakReference
kommer in.
ta till exempel detta:
class MyMemoryExpensiveClass {
companion object {
var reference: WeakReference<MyMemoryExpensiveClass>? = null
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let {
it.get()?.let(block)
}
}
}
init {
reference = WeakReference(this)
}
}
Nu är det bara med en WeakReference. För att minska denna pannplatta kan vi använda en anpassad egendomsdelegat för att hjälpa oss så:
class WeakReferenceDelegate<T>(initialValue: T? = null) : ReadWriteProperty<Any, T?> {
var reference = WeakReference(initialValue)
private set
override fun getValue(thisRef: Any, property: KProperty<*>): T? = reference.get()
override fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
reference = WeakReference(value)
}
}
Så nu kan vi använda variabler som är lindade med WeakReference
precis som vanliga nollbara variabler!
class MyMemoryExpensiveClass {
companion object {
var reference: MyMemoryExpensiveClass? by WeakReferenceDelegate<MyMemoryExpensiveClass>()
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let(block)
}
}
init {
reference = this
}
}