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

7
我将尝试将一个接口的回调实现(该接口定义在类A中)赋值给另一个类B中定义的变量。假设类A有一个OnSomethingHappens接口,其中定义了一个doSomething方法。
在类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
   }
 }

但编译器提示我的回调变量为"expecting member declaration",并且在对象中提示"name expected"。我做错了什么吗?

相反,我可以通过以下方式定义和同时分配回调变量:

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

为什么?有哪些区别和可能的解决方案?

我尝试添加更多细节以便您更好地理解。我在我的Android应用程序中使用我上面编写的代码行,类B对我来说是一个片段,而类A是一个公共类,其中包含我从片段中使用的一些方法,以便为我完成一些工作。当类A结束此工作时,它会使用我在片段内创建类A实例时传递的回调(即构造函数中的回调),调用接口OnSomethingHappens中定义的方法doSomethig()。该片段实现此方法,并像我上面展示的那样准备回调变量,并将其传递给类A。 - user9257465
3个回答

2
我正在尝试使用以下代码分配实现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块。

而且,如果你可以直接在定义处或在init内初始化callback,那么一开始使用lateinit就没有意义了。


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

或者在初始化块中(在这种情况下,甚至不需要lateinit):
class A {
    var x: X

    init {
        x = X()
    }
}

虽然我无法解释如何解决您确切的问题,因为我无法完全理解哪个类中包含哪些代码,但我希望这些示例和解释能够有所帮助。

1

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

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。希望这能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接