必须初始化变量'runnable' [英] Variable 'runnable' must be initialized
问题描述
为什么Kotlin抱怨这个:
Why does Kotlin complains about this:
class MyActivity : Activity {
private var handler:Handler = Handler()
private var runnable: Runnable = Runnable {
/* Do something very important */
handler.postDelayed(this@MyActivity.runnable, 5000)
}
}
编译器抱怨变量'runnable'必须是行中的初始化
是由处理程序再次发布的。
这在普通Java中有效:
Compiler complains that Variable 'runnable' must be initialized
in the Line were it's posted again by handler.
This does work in plain Java:
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
handler.postDelayed(runnable, 5000);
}
};
推荐答案
Kotlin认为财产未初始化直到其初始化程序结束因此,它不能在自己的初始化程序中使用,即使在lambdas中也是如此。这种语义类似于其初始化程序中的局部变量用法的限制一>。
Kotlin considers a property uninitialized until the end of its initializer, therefore it cannot be used inside its own initializer, even in lambdas. This semantics is similar to the limitation of local variable usage inside its initializer.
有几种解决方法:
-
使用对象表达式,可让您引用
此
声明的对象:
Use object expression which lets you reference
this
of the declared object:
private var runnable: Runnable = object : Runnable {
override fun run() {
/* Do something very important */
handler.postDelayed(this, 5000)
}
}
这只适用于作为lambda的替代品的接口,并且不是很完美。
This works well only for interfaces as a replacement for lambdas and is not very pretty altogether.
使用 lateinit var
或委托属性 /kotlinlang.org/api/latest/jvm/stdlib/kotlin.properties/-d elegates / not-null.htmlrel =noreferrer> Delegates.notNull()
:
Use lateinit var
or a delegated property with Delegates.notNull()
:
private lateinit var runnable: Runnable
init {
runnable = Runnable {
/* Do something very important */
handler.postDelayed(runnable, 5000)
}
}
相同的初始化程序可以使用此声明:
The same initializer will work with this declaration:
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)
}
}
这篇关于必须初始化变量'runnable'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!