Kotlin,为什么我写的接口只有一个抽象方法却无法使用SAM?

211 阅读1分钟

问题如下:

interface People {
    fun study(className: String)
}

fun foo(p: People) {
    p.study("Kotlin SAM")
}

fun main() {
    
    //1.给按钮设置点击监听时的lambdas写法  纯正的SAM写法
    binding.btn.setOnClickListener {
        //todo
    }
    
    //2.报错:为何我无法这样写?
    foo { className ->
        //todo
    }

}

然后我就去查看了点击事件监听函数的参数类型:

public interface OnClickListener {
    void onClick(View var1);
}

看完,好像没什么不一样的呀,就是一个用 Java,另一个用 Kotlin

经过一系列的查阅,诶,问题就出现在这个差别上。

Java8 提出了单一抽象接口的概念,所以使用 Java 写的接口是天然支持 SAM 的,而如果使用 Kotlin 写的普通接口的话是无法使用的。

Kotlin1.4 版本开始支持 SAM ,之前不支持貌似是因为已经有函数类型和高阶函数了。

要在 Kotlin 中使用 SAM 的话,则需要使用 Function interfaces

// 使用关键字 fun
fun interface People {
    fun study(className: String)
}

使用关键字 fun 后即可使用 SAM 了。

参考

Functional (SAM) interfaces

What is Kotlin SAM ?

Kotlin与java8的SAM转换对比(进阶)

Support for Kotlin SAM in release 1.4