必须初始化变量“runnable" [英] Variable 'runnable' must be initialized

查看:45
本文介绍了必须初始化变量“runnable"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 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 或带有 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()

  • 实施和使用 self- 对你自己的初始化器的引用:

    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
    }
    

    然后你可以写一些类似的东西

    And then you can write something like

    private var runnable: Runnable = selfReference { 
        Runnable {
            /* Do something very important */
            handler.postDelayed(self, 5000)
        } 
    }
    

  • 这篇关于必须初始化变量“runnable"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆