Ключевое слово by в Kotlin
Ключевое слово by связывает ваш тип с объектом,
который выполняет работу за вас. В заголовке класса
оно идёт после интерфейса: ClassName(...) :
Interface by parameter. У свойства - между
именем и типом: val x: Type by delegate.
Один и тот же символ, два разных места в синтаксисе.
Делегирование интерфейса требует, чтобы выражение
справа от by было доступно в конструкторе -
обычно это параметр:
interface Clock {
fun now(): String
}
class SystemClock : Clock {
override fun now(): String = "12:00"
}
class App(clock: Clock) : Clock by clock {
fun label(): String = "time=${now()}"
}
У свойства by указывает делегат из
kotlin.properties или свой объект.
Чтение и запись свойства превращаются в вызовы
getValue и setValue (для записи):
import kotlin.properties.Delegates
class Config {
var port: Int by Delegates.observable(8080) {
_, old, new ->
println("$old->$new")
}
}
Ключевое слово by нельзя подставить произвольное выражение
в заголовке класса - только ссылка на объект,
реализующий интерфейс. У свойства делегат создают
один раз при инициализации экземпляра (или класса
для companion и верхнего уровня - по правилам
объявления).
Объявите interface Id с fun raw(): Int,
class FixedId(val n: Int) : Id и
class Wrap(i: Id) : Id by i.
Выведите Wrap(FixedId(7)).raw().
Объявите class Box. Объявите свойство
val tag: String by lazy {
"box-" + System.nanoTime()
}. Создайте два объекта Box
и выведите оба значения tag - строки
должны различаться.