Приведи примеры делегатов свойств

«Приведи примеры делегатов свойств» — вопрос из категории Kotlin, который задают на 23% собеседований Android Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Делегаты свойств (by) позволяют делегировать геттеры/сеттеры свойств другому объекту. Примеры:

Lazy инициализация:

val heavyObject: HeavyClass by lazy {
    HeavyClass() // создастся только при первом обращении
}

Observable свойства:

var name: String by Delegates.observable("") { _, old, new ->
    println("$old -> $new")
}

Хранение в Map:

class User(val map: Map<String, Any>) {
    val name: String by map
    val age: Int by map
}

val user = User(mapOf("name" to "Alex", "age" to 25))

Кастомный делегат:

class LoggingDelegate<T>(private var value: T) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>) = value.also {
        println("Read ${property.name} = $it")
    }
    operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) {
        println("Set ${property.name} = $newValue")
        value = newValue
    }
}

var counter: Int by LoggingDelegate(0)