变量'runnable'必须被初始化
为什么Kotlin抱怨这个:
class MyActivity : Activity { private var handler:Handler = Handler() private var runnable: Runnable = Runnable { /* Do something very important */ handler.postDelayed(this@MyActivity.runnable, 5000) } }
编译器抱怨Variable 'runnable' must be initialized
,然后被处理程序再次发布。 这在普通的Java中工作:
private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { handler.postDelayed(runnable, 5000); } };
Kotlin认为一个属性没有被初始化,直到它的初始化器结束,所以它不能在自己的初始化器中使用,即使在lambdas中也是如此。 这种语义与其初始化程序中局部变量使用的局限性相似。
有几个解决方法:
-
使用对象表达式可以让你引用
this
声明的对象:private var runnable: Runnable = object : Runnable { override fun run() { /* Do something very important */ handler.postDelayed(this, 5000) } }
这只适用于作为lambda的替代接口,并不是非常漂亮。
-
使用
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) } }
你也可以使用
private var runnable: Runnable = Runnable { /* Do something very important */ handler.postDelayed(runnable(), 5000) } private fun runnable() = runnable
- Dagger2 @Nullable注释与Kotlin
- 如何使用Android kotlin仅在日期选取器对话框中显示日期和月份
- Android – ViewDataBinding.inflate不会膨胀嵌套的自定义视图
- 在BottomsheetDialog中使用setcontentview时,会出现类似“以下函数都不能用提供的参数调用”的错误
- 未解决的参考:使用greendao和kotlin的DaoSession
- 只改变一个类的方法从java到kotlin
- Kotlin – 将List转换为MutableList的最常用的方法
- 在Kotlin中覆盖复杂类型的Java方法
- Kotlin类型不匹配编译错误:需要成功<T>,找到MyError