Kotlin
Delegowane właściwości
Szukaj…
Wprowadzenie
Kotlin może delegować implementację właściwości do obiektu obsługi. Uwzględniono niektóre standardowe procedury obsługi, takie jak leniwa inicjalizacja lub obserwowalne właściwości. Można również tworzyć niestandardowe programy obsługi.
Leniwa inicjalizacja
val foo : Int by lazy { 1 + 1 }
println(foo)
Przykład drukuje 2
.
Obserwowalne właściwości
var foo : Int by Delegates.observable("1") { property, oldValue, newValue ->
println("${property.name} was changed from $oldValue to $newValue")
}
foo = 2
Przykładowe wydruki foo was changed from 1 to 2
Właściwości wspierane przez mapę
val map = mapOf("foo" to 1)
val foo : String by map
println(foo)
Przykład drukuje 1
Niestandardowe delegowanie
class MyDelegate {
operator fun getValue(owner: Any?, property: KProperty<*>): String {
return "Delegated value"
}
}
val foo : String by MyDelegate()
println(foo)
W tym przykładzie wydrukowano Delegated value
Delegat Może być stosowany jako warstwa zmniejszająca płytę grzewczą
Rozważmy system WeakReference<T>
Kotlin i WeakReference<T>
.
Powiedzmy, że musimy zapisać jakiś odnośnik i chcieliśmy uniknąć wycieków pamięci, oto gdzie pojawia się WeakReference
.
weźmy na przykład to:
class MyMemoryExpensiveClass {
companion object {
var reference: WeakReference<MyMemoryExpensiveClass>? = null
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let {
it.get()?.let(block)
}
}
}
init {
reference = WeakReference(this)
}
}
Teraz jest to tylko jeden WeakReference. Aby zmniejszyć tę liczbę, możemy użyć niestandardowego delegata właściwości, który pomoże nam w następujący sposób:
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)
}
}
Teraz możemy używać zmiennych opakowanych w WeakReference
podobnie jak normalne zmienne dopuszczające wartości zerowe!
class MyMemoryExpensiveClass {
companion object {
var reference: MyMemoryExpensiveClass? by WeakReferenceDelegate<MyMemoryExpensiveClass>()
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let(block)
}
}
init {
reference = this
}
}