简体   繁体   English

无法为 Kotlin 声明的函数删除冗余 SAM 构造函数,但适用于 Java 声明的函数

[英]Redundant SAM-constructor can't be remove for Kotlin declared function, but works on Java declared function

I have a Java Class function as below我有一个 Java 类函数,如下所示

public void setPositiveButton(int resId, DialogInterface.OnClickListener listener) 

I also have the same Kotlin Class function as below我也有如下相同的 Kotlin 类函数

fun setPositiveButton(resId: Int, listener: DialogInterface.OnClickListener)

When I call them from a Kotlin code当我从 Kotlin 代码调用它们时

    javaClassObj.setPositiveButton(R.string.some_string,
            DialogInterface.OnClickListener { _, _ -> someFunc()})

    kotlinClassObj.setPositiveButton(R.string.some_string,
            DialogInterface.OnClickListener { _, _ -> someFunc()})

The Java Class function call could be reduced, but not the Kotlin Class function可以减少 Java Class 函数调用,但不能减少 Kotlin Class 函数

    javaClassObj.setPositiveButton(R.string.some_string,
            { _, _ -> someFunc()})

    kotlinClassObj.setPositiveButton(R.string.some_string,
            DialogInterface.OnClickListener { _, _ -> someFunc()})

Why can't the Kotlin function call reduce the redundant SAM-Constructor as per enabled for Java?为什么 Kotlin 函数调用不能减少为 Java 启用的冗余 SAM-Constructor?

Why would you use SAM in kotlin?为什么要在 kotlin 中使用 SAM? while it has native support for functions.虽然它具有对功能的本机支持。

The SAM convention is used in java8 as a workaround not having native function support. SAM 约定在 java8 中用作没有本机函数支持的解决方法。

from kotlin doc#sam-conversions :来自kotlin doc#sam-conversions

Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.请注意,SAM 转换仅适用于接口,不适用于抽象类,即使它们也只有一个抽象方法。

Also, note that this feature works only for Java interop;另请注意,此功能仅适用于 Java 互操作; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.由于 Kotlin 具有适当的函数类型,因此无需将函数自动转换为 Kotlin 接口的实现,因此不受支持。

you should then declare a function directly.然后你应该直接声明一个函数。

fun setPositiveButton(resId: Int, listener: (DialogInterface, Int) -> Unit) {
    listener.invoke(
            //DialogInterface, Int
    )
}

and then it can be used然后就可以使用了

setPositiveButton(1, { _, _ -> doStuff() })

In kotlin 1.4 you can use SAM conversions for Kotlin classes.kotlin 1.4 中,您可以对 Kotlin 类使用 SAM 转换。

fun interface Listener {
    fun listen()
}

fun addListener(listener: Listener) = a.listen()

fun main() {
    addListener {
        println("Hello!")
    }
}

Extending @humazed answer as compiler complains that在编译器抱怨时扩展@humazed 答案

lambda argument should be moved out of parenthesis lambda 参数应该从括号中移出

setPositiveButton("ok"){_,_ -> doSomething()}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM