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

Ely*_*lye 7 java kotlin

我有一个Java类函数如下

public void setPositiveButton(int resId, DialogInterface.OnClickListener listener) 
Run Code Online (Sandbox Code Playgroud)

我也有如下的Kotlin类功能

fun setPositiveButton(resId: Int, listener: DialogInterface.OnClickListener)
Run Code Online (Sandbox Code Playgroud)

当我从Kotlin代码中调用它们时

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

    kotlinClassObj.setPositiveButton(R.string.some_string,
            DialogInterface.OnClickListener { _, _ -> someFunc()})
Run Code Online (Sandbox Code Playgroud)

可以减少Java类函数调用,但不能减少Kotlin类函数

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

    kotlinClassObj.setPositiveButton(R.string.some_string,
            DialogInterface.OnClickListener { _, _ -> someFunc()})
Run Code Online (Sandbox Code Playgroud)

为什么Kotlin函数调用不能根据Java启用减少冗余的SAM-Constructor?

hum*_*zed 12

你为什么要在kotlin中使用SAM?虽然它有功能的原生支持.

SAM约定在java8中用作没有本机功能支持的工作.

来自kotlin doc#sam-conversions:

请注意,SAM转换仅适用于接口,而不适用于抽象类,即使它们只有一个抽象方法.

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

然后你应该直接声明一个函数.

fun setPositiveButton(resId: Int, listener: (DialogInterface, Int) -> Unit) {
    listener.invoke(
            //DialogInterface, Int
    )
}
Run Code Online (Sandbox Code Playgroud)

然后它可以使用

setPositiveButton(1, { _, _ -> doStuff() })
Run Code Online (Sandbox Code Playgroud)

  • (可怕的)Android 开发人员指南告诉人们使用 SAM。感谢您解释为什么它不好。 (3认同)
  • 我猜这是从 Java 是唯一语言的时代开始的,负责转换文档以支持 kotlin 的工程师并没有费心更改代码以使用 kotlin 方式,而只是将 java 代码转换为 kotlin。或者他可能会创建一个脚本来将其转换为自动化他的工作:D (2认同)