我有一个简单的 Kotlin 界面:
@FunctionalInterface
interface ServiceMethod<T> {
fun doService(): T
}
Run Code Online (Sandbox Code Playgroud)
尽管名称如此,但这本质上与 Java 的供应商功能接口相同。唯一的区别是我可以实现Supplier,而不能实现自己的。
val supplier = Supplier<String> {
"Hello"
}
val serviceMethod = ServiceMethod<String> {
"Hello"
}
Run Code Online (Sandbox Code Playgroud)
ServiceMethod 实现给了我一个编译器错误,提示“接口 ServiceMethod 没有构造函数”。嗯?当然不是!这是一个功能界面。
我知道我可以把它写成一个匿名内部类:
val serviceMethod = object : ServiceMethod<String> {
override fun doService(): String {
return "Hello"
}
}
Run Code Online (Sandbox Code Playgroud)
但这要冗长得多。在这种情况下,我可以只使用供应商接口,但这不适用于其他接口。我不应该用 Java 编写接口,只是为了能够在 Kotlin 中使用 lambda。我宁愿为我所有的 Kotlin 接口使用 lambda,尤其是因为我将编写很多这样的接口。我错过了一些明显的东西吗?
Sam*_*Sam 20
fun从 Kotlin 1.4 开始使用interface 修饰符在 Kotlin 1.3 及更早版本中,Supplier仅 Java 接口支持SAM(单一抽象方法)转换,您可以在其中像使用 lambda 函数一样实例化接口。
语言设计者最初认为SAM 转换对 Kotlin 接口没有用,因为Kotlin 函数已经有一个 type。例如,您的doService函数的类型可以写为() -> T. 您可以简单地编写,而不是创建一个实现接口的对象:
val serviceMethod: () -> String = { "Hello" }
Run Code Online (Sandbox Code Playgroud)
Kotlin 1.4 为 Kotlin 接口添加了 SAM 转换,但它并不是对每个接口都开箱即用。相反,您必须将特殊fun修饰符应用于 Kotlin 接口以使其符合 SAM 转换的条件。
在您的示例中,它看起来像这样:
fun interface ServiceMethod<T> {
fun doService(): T
}
Run Code Online (Sandbox Code Playgroud)
添加修饰符后,您可以完全按照您在问题中的希望使用 lambda 创建一个实例。
val serviceMethod = ServiceMethod<String> { "Hello" }
Run Code Online (Sandbox Code Playgroud)
您可以在功能接口的Kotlin 文档中了解更多信息。
| 归档时间: |
|
| 查看次数: |
809 次 |
| 最近记录: |