变量“可运行”必须初始化

FelixLegions的General:

为什么Kotlin对此抱怨:

class MyActivity : Activity {
  private var handler:Handler = Handler()

  private var runnable: Runnable = Runnable {
    /* Do something very important */
    handler.postDelayed([email protected], 5000)
  }
}

编译器抱怨Variable 'runnable' must be initialized在Line中由处理程序再次发布。这在纯Java中确实有效:

private Handler handler = new Handler();

private Runnable runnable = new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(runnable, 5000);
    }
};
热键:

Kotlin认为一个属性在其初始化程序结束之前尚未初始化,因此即使在lambda中也无法在其自己的初始化程序中使用该属性。这种语义类似于其初始化程序内部局部变量使用的限制

有几种解决方法:

  • 使用对象表达式可以引用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)
        } 
    }
    

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章