Поиск…


Вступление

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
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow