Home Articles

Kotlin,如何将回调实现分配给变量

Asked
Viewed 1864 times
2

我正在尝试将接口的回调实现(在类A中定义)分配给在另一个类B中定义的变量 . 假设类A具有定义doSomething方法的OnSomethingHappens接口 .

在B类中我已经定义了我的回调变量,如下所示:

private lateinit var callback:A.OnSomethingHappens

我需要以这种方式创建一个类A的实例,将回调变量传递给构造函数:

myinstanceA = A(callback)

我正在尝试使用以下代码分配实现 A.OnSomethingHappens 的匿名类的实例:

callback = object : A.OnSomethingHappens {
   override fun doSomething(..){
      //here I put the implementation of this method
   }
 }

但编译器为我的回调变量说“期待成员声明”,对象说“期望名称” . 我做错了什么?

相反,我能够定义并同时以这种方式分配回调变量:

private var callback = object : A.OnSomethingHappens {
      override fun doSomething(..){
        //here I put the implementation of this method
      }
    }

为什么?哪些是差异和可能的解决方案?

3 Answers

  • 1

    从代码片段减少到如此小的片段并不明显,但你的问题是你在一个类的体内写下了赋值,但不是在函数内部 .

    以下是有效声明和立即分配的示例:

    class A {
        var x: X? = X()
    }
    

    这是一个无效赋值的示例,它将任意表达式放在类的主体中:

    class A {
        lateinit var x: X
    
        x = X()        // expression placed inside the class body, invalid syntax
        someFunction() // extra example, calling functions here is invalid in the same way
    }
    

    相反,您可以将此初始化放在函数中:

    class A {
        lateinit var x: X
    
        fun initializeX() {
            x = X()
        }
    }
    

    或者在initializer block内(在这种情况下,你甚至不需要 lateinit ):

    class A {
        var x: X
    
        init {
            x = X()
        }
    }
    

    虽然我无法解释如何解决您的确切问题,因为我无法理解哪个类在哪个类中,我希望这些示例和解释有所帮助 .

  • 0

    我正在尝试使用以下代码分配实现A.OnSomethingHappens的匿名类的实例:...

    这应该工作,但只在一个方法内:

    class B {
        private lateinit var callback:A.OnSomethingHappens
    
        fun someMethod() {
            callback = object : A.OnSomethingHappens { ... }
        }
        ...
    }
    

    给定错误消息并且 private var 编译(不在方法内),您试图直接在类的主体中设置它:

    class B {
        private lateinit var callback:A.OnSomethingHappens
    
        callback = object : A.OnSomethingHappens { ... }
        ...
    }
    

    这是非法的:您可以在那里编写的唯一代码是成员定义和 init 块 .

    此外,如果您可以直接将 callback 初始化到定义的位置或 init 内,那么首先没有任何意义 lateinit .

  • 0

    嗯,让我提出一个变体 . 这对我来说更简单:

    import android.util.Log
    
    class SomeClass {
    
        fun mainMethod() {
    
            ClassWithCallback(
                    { myBackValue: String ->
                        logMyString(myBackValue)
                    }
            )
    
            //simplify
            ClassWithCallback({ logMyString(it) })
        }
    
        private fun logMyString(myBackValue: String) {
            Log.d("SomeClass", myBackValue)
        }
    }
    
    class ClassWithCallback(private val myCallBack: (myBackValue: String) -> Unit) {
    
        init {
            // we do something here and back it by callback
    
            val myString = "Hello! Pass me back!"
            myCallBack.invoke(myString.toUpperCase())
        }
    }
    

    使用Kotlin lambdas . 希望这会帮助你 .

Related