【问题标题】:lambda expression on interface in KotlinKotlin 接口上的 lambda 表达式
【发布时间】:2018-06-14 10:21:41
【问题描述】:

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

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

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

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

activity.setOnBackPressed { /* Do something */ }

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

activity.setOnBackPressed(OnBackPressedListener { /* Do something */ })

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

activity.setOnBackPressed(object: OnBackPressedListener {
            override fun onBackPressed() {
                /* Do something */
            }
        })

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

谢谢

【问题讨论】:

    标签: java android lambda interface kotlin


    【解决方案1】:

    lambda 版本仅在 kotlin 与 java 互操作时有效,因为 SAM Conversions,请参阅 the official documents

    还请注意,此功能仅适用于 Java 互操作;自从科特林 具有适当的函数类型,自动将函数转换为 Kotlin 接口的实现是不必要的,因此 不支持。

    所以如果你想使用 lambda 来设置纯 kotlin 的监听器,你可以像这样定义你的 listenersetOnBackPressed 方法:

    var listener: (() -> Unit)? = null
    
    fun setOnBackPressed(l: () -> Unit) {
        listener = l
    }
    

    然后调用它:

    listener?.invoke()
    

    【讨论】:

    • invoke 究竟做了什么?
    • @IgorGanapolsky 因为 kotlin 中的 lambda 被编译成 Function 类对象,其中只有 invoke() 方法 - invoke() 只执行 lambda 块。通常我们只写 lambda(),它与 ​​lambda.invoke() 相同。但是对于可空的 lambda,我们必须使用问号来保证空安全
    • inlinecrossinline 会在这个特定的执行过程中扮演什么角色吗?
    【解决方案2】:

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

    如果你真的想使用OnBackPressedListener,你可以把它包装在inline函数中,比如:

    inline fun backPress(crossinline action:()->Unit):OnBackPressedListener {
        return object: OnBackPressedListener {
            override fun onBackPressed() {
                action()
            }
        }
    }
    

    然后设置监听器

    activity.setOnBackPressed(backPress {  
    /* Do something */
    })
    

    【讨论】:

    • crossinline action 是做什么的?以及为什么我们必须创建一个全新的对象...
    • @IgorGanapolsky 我们创建一个新对象只是因为问题的作者想要使用它。 Crossinline 只是限制在内联 lambda 中使用“return”,因为它可以完成错误的功能
    • 所以你的crossinline 什么也没返回?
    猜你喜欢
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 2014-04-18
    • 1970-01-01
    相关资源
    最近更新 更多