Kotlin界面上的lambda表达式

nob*_*710 6 java lambda android interface kotlin

我正在将Java项目转换为Kotlin,我很惊讶接口使得Kotlin中的代码比Java中的代码更重.

示例:我想在MyFragment中设置MainActivity中的onBackPressListener.

文件1:MainActivity,文件2:MyFragment,文件3:OnBackPressedListener(接口)

Java中的文件1,Kotlin中的文件2,Java中的文件3:

activity.setOnBackPressed { /* Do something */ }
Run Code Online (Sandbox Code Playgroud)

Kotlin中的文件1,Kotlin中的文件2,Java中的文件3:

activity.setOnBackPressed(OnBackPressedListener { /* Do something */ })
Run Code Online (Sandbox Code Playgroud)

Kotlin中的文件1,Kotlin中的文件2,Kotlin中的文件3:

activity.setOnBackPressed(object: OnBackPressedListener {
            override fun onBackPressed() {
                /* Do something */
            }
        })
Run Code Online (Sandbox Code Playgroud)

是否可以在Kotlin中使用3个文件并使用lambda来设置监听器?(在Kotlin中获取更多代码真令人沮丧..)

谢谢

Hon*_*uan 6

lambda版本仅在kotlin与java互操作时才有效,因为SAM Conversions请参阅官方文档.

另请注意,此功能仅适用于Java互操作; 由于Kotlin具有适当的函数类型,因此不需要将函数自动转换为Kotlin接口的实现,因此不受支持.

所以,如果你想使用lambda来设置纯科特林听众,您可以定义listenersetOnBackPressed方法如下:

var listener: (() -> Unit)? = null

fun setOnBackPressed(l: () -> Unit) {
    listener = l
}
Run Code Online (Sandbox Code Playgroud)

然后通过以下方式调用它:

listener?.invoke()
Run Code Online (Sandbox Code Playgroud)

  • @IgorGanapolsky,因为kotlin中的lambda仅在内部具有invoke()方法的情况下编译为Function类对象-invoke()仅执行lambda块。通常,我们只编写与lambda.invoke()相同的lambda()。但是对于可为空的lambda,我们必须使用问号来确保安全性 (2认同)

And*_*lov 5

你在使用Kotlin时使用Java风格=)

如果你真的想要使用,OnBackPressedListener你可以将其包装在inline功能中,例如:

inline fun backPress(crossinline action:()->Unit):OnBackPressedListener {
    return object: OnBackPressedListener {
        override fun onBackPressed() {
            action()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需设置监听器

activity.setOnBackPressed(backPress {  
/* Do something */
})
Run Code Online (Sandbox Code Playgroud)