Kotlin
Делегированные свойства
Поиск…
Вступление
Kotlin может делегировать реализацию свойства объекту обработчика. Некоторые стандартные обработчики включены, например, ленивая инициализация или наблюдаемые свойства. Также могут быть созданы пользовательские обработчики.
Ленивая инициализация
val foo : Int by lazy { 1 + 1 }
println(foo)
Пример печатает 2
.
Наблюдаемые свойства
var foo : Int by Delegates.observable("1") { property, oldValue, newValue ->
println("${property.name} was changed from $oldValue to $newValue")
}
foo = 2
Пример печати foo was changed from 1 to 2
Свойства карты
val map = mapOf("foo" to 1)
val foo : String by map
println(foo)
Пример: 1
Пользовательское
class MyDelegate {
operator fun getValue(owner: Any?, property: KProperty<*>): String {
return "Delegated value"
}
}
val foo : String by MyDelegate()
println(foo)
Пример отображает Delegated value
Делегат Может использоваться как слой для уменьшения шаблона
Рассмотрим систему Null Type Kotlin и WeakReference<T>
.
Итак, скажем, нам нужно сохранить какую-то ссылку, и мы хотели избежать утечек памяти, здесь WeakReference
.
возьмите, например, следующее:
class MyMemoryExpensiveClass {
companion object {
var reference: WeakReference<MyMemoryExpensiveClass>? = null
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let {
it.get()?.let(block)
}
}
}
init {
reference = WeakReference(this)
}
}
Теперь это только с одним WeakReference. Чтобы уменьшить этот шаблон, мы можем использовать персонализированный делегат свойств, чтобы помочь нам в этом:
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)
}
}
Итак, теперь мы можем использовать переменные, которые обернуты с помощью WeakReference
как обычные переменные с WeakReference
значением!
class MyMemoryExpensiveClass {
companion object {
var reference: MyMemoryExpensiveClass? by WeakReferenceDelegate<MyMemoryExpensiveClass>()
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let(block)
}
}
init {
reference = this
}
}