Ответ 1
Kotlin считает свойство неинициализированным до конца его инициализатора, поэтому он не может использоваться внутри своего собственного инициализатора даже в лямбдах. Эта семантика аналогична ограничению использования локальной переменной внутри ее инициализатора.
Существует несколько способов:
-
Используйте выражение объекта, которое позволяет ссылаться на
this
объявленного объекта:private var runnable: Runnable = object : Runnable { override fun run() { /* Do something very important */ handler.postDelayed(this, 5000) } }
Это хорошо работает только для интерфейсов в качестве замены для лямбда и совсем не совсем красиво.
-
Используйте
lateinit var
или делегированное свойство сDelegates.notNull()
:private lateinit var runnable: Runnable init { runnable = Runnable { /* Do something very important */ handler.postDelayed(runnable, 5000) } }
Тот же инициализатор будет работать с этим объявлением:
private var runnable: Runnable by Delegates.notNull()
-
Внедрить и использовать самостоятельную ссылку для инициализаторов самостоятельно:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) { val self: T by lazy { inner ?: throw IllegalStateException("Do not use `self` until initialized.") } private val inner = initializer() } fun <T> selfReference(initializer: SelfReference<T>.() -> T): T { return SelfReference(initializer).self }
И тогда вы можете написать что-то вроде
private var runnable: Runnable = selfReference { Runnable { /* Do something very important */ handler.postDelayed(self, 5000) } }