kotlin - 为什么我们需要在 Kotlin 中显式的函数接口(interface)修饰符?

标签 kotlin

考虑一个用 Java 定义的 SAM

public interface Transform {
   public String apply(String str);
}

此接口(interface)自动支持 Kotlin 中的 lambda 到类型转换

fun run(transform: Transform) {
    println(transform.apply("world"))
}

run { x -> "Hello $x!!" } // runs fine without any issues

但现在考虑一个 Kotlin 接口(interface)

interface Transform2 {

    fun apply(str: String): String

}

现在调用 run 函数的唯一方法是创建 Transform2 的匿名实例

run(object : Transform2 {
        override fun transform(str: String): String = "hello $str!!"
})

但如果我们将 Transform2 接口(interface)设为函数式接口(interface),则以下是可能的

run { str -> "hello $str!!" }

为什么 Kotlin 编译器不能自动将转换 lambda 类型转换为匹配的接口(interface)(就像它对 Java 接口(interface)所做的那样),而无需将所述接口(interface)显式标记为函数式接口(interface)。

最佳答案

我在 comment 中找到了某种理由。在 KT-7770 :

... treating all the applicable interfaces as SAM might be too unexpected/implicit: one having a SAM-applicable interface may not assume that it will be used for SAM-conversions. Thus, adding another method to the interface becomes more painful since it might require changing syntax on the call sites (e.g. transforming callable reference to object literal).

Because of it, current vision is adding some kind of modifier for interfaces that when being applied:

  • Adds a check that the interface is a valid SAM
  • Allows SAM-conversions on call sites for it

Something like this:

fun interface MyRunnable {
     fun run()
}

基本上,他的意思是,如果默认情况下隐式完成 SAM 转换,并且我在接口(interface)中添加了一些新方法,则将不再执行 SAM 转换,并且每个使用转换的地方都需要更改。 “有趣”这个词是告诉编译器检查接口(interface)确实只有一个抽象方法,也告诉调用站点这确实是一个SAM接口(interface),他们可以期待作者不要突然添加新的抽象接口(interface)的方法,突然破坏了他们的代码。

线程继续讨论why can't the same argument can't be applied to Java ,以及 reason本质上归结为“Java 不是 Kotlin”。

关于kotlin - 为什么我们需要在 Kotlin 中显式的函数接口(interface)修饰符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70569535/

相关文章:

multithreading - 将 channel 桥接到序列

android - 如何将过滤器与 Algolia 的 InstantSearch 一起使用?

kotlin - 函数中Unit-return的目的是什么

android - 如何使用一个 Activity 中的按钮在第二个 Activity 中执行某些操作?

安卓错误: Can't find ColorStateList from drawable resource while using dialogs

android - 如何从任务中删除监听器?

android - 将 LiveData<Resource<User>> 转换为 LiveData<User> 时的类型干扰问题

intellij-idea - 如何调试Kotlin koan?

spring - 如何在 Spring Boot 中注册新的集合工厂

java - Android Studio 在 generatedJava 文件夹中生成 AIDL java 文件,但包名错误