Variable 'runnable' must be initialized

前端 未结 2 1060
[愿得一人]
[愿得一人] 2020-12-10 03:12

Why does Kotlin complains about this:

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

  private var runnable: Runnable = Runnable {
         


        
相关标签:
2条回答
  • 2020-12-10 03:36

    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.

    There are several workarounds:

    • 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)
          }
      }
      

      This works well only for interfaces as a replacement for lambdas and is not very pretty altogether.

    • 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()
      
    • Implement and use self-reference for initializers on your own:

      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)
          } 
      }
      
    0 讨论(0)
  • 2020-12-10 03:37

    You can also use

    private var runnable: Runnable = Runnable {
        /* Do something very important */
        handler.postDelayed(runnable(), 5000)
    }
    
    private fun runnable() = runnable
    
    0 讨论(0)
提交回复
热议问题