首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在Kotlin中需要一个显式函数接口修饰符?

为什么在Kotlin中需要一个显式函数接口修饰符?
EN

Stack Overflow用户
提问于 2022-01-03 17:41:56
回答 2查看 177关注 0票数 4

考虑用Java定义的SAM

代码语言:javascript
复制
public interface Transform {
   public String apply(String str);
}

此接口支持lambda自动在Kotlin中进行类型转换。

代码语言:javascript
复制
fun run(transform: Transform) {
    println(transform.apply("world"))
}

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

但是现在考虑一下Kotlin接口

代码语言:javascript
复制
interface Transform2 {

    fun apply(str: String): String

}

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

代码语言:javascript
复制
run(object : Transform2 {
        override fun transform(str: String): String = "hello $str!!"
})

但是,如果我们将Transform2接口作为一个功能接口,那么下面的内容是可能的

代码语言:javascript
复制
run { str -> "hello $str!!" }

为什么Kotlin编译器不需要显式地将这些接口标记为一个功能接口,就不能自动将强制转换的lambda键入到匹配的接口(就像它对Java接口所做的那样)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-03 18:14:15

我在评论 in KT-7770中找到了某种理由

..。将所有可应用的接口视为SAM可能太出乎意料/隐含:一个具有SAM可应用接口的接口可能不会假设它将用于SAM转换。因此,向接口添加另一个方法会变得更加痛苦,因为它可能需要更改调用站点上的语法(例如,将可调用引用转换为对象文本)。 正因为如此,当前的设想是在应用时为接口添加某种修饰符:

  • 添加一个检查接口是否为有效的SAM。
  • 允许SAM-在呼叫站点上转换它

就像这样:

有趣的接口MyRunnable {趣味运行()}

基本上,他是说,如果SAM转换是默认情况下隐式完成的,而且我在接口中添加了一些新方法,那么SAM转换将不再被执行,使用转换的每个地方都需要更改。“乐趣”一词是为了告诉编译器检查接口确实只有一个抽象方法,并告诉调用站点这确实是一个SAM接口,他们可以期望作者不会突然向接口添加新的抽象方法,从而突然中断他们的代码。

线程继续讨论为什么不能将相同的参数应用于Java原因本质上归结为"Java“。

票数 7
EN

Stack Overflow用户

发布于 2022-01-03 19:13:32

这是猜测,但我强烈怀疑其中一个原因是避免在Kotlin的更自然的方法之上鼓励使用功能接口。

函数接口是Java解决向Java语言中添加lambda的问题的解决方案,这种方式涉及到最近的更改和风险,以及与Java在没有这些接口的近20年中的最佳实践的最大兼容性:使用实现命名接口的匿名类。 需要无数不同的命名接口,如SupplierBiFunctionDoublePredicate…。每个接口都有各自的方法和参数名称,每个接口都与所有其他接口不兼容--以及与多年来人们开发的所有其他接口不兼容。-但它们都是不相关和不兼容的。) 和所有这些都是为了弥补Java没有一流函数这一事实。

Kotlin 一级函数,它是一种更通用、更优雅、更强大的方法--. (例如,您可以使用单个参数编写lambda (或函数或函数文字),并在需要接受单个参数的函数的任何地方使用它,而不必担心它的确切接口。 无需在类似的界面之间进行选择。或者写你自己的,如果没有的话。当 不能推断正确的接口类型时,就不会出现任何隐藏的问题。) 所有的标准库都使用函数类型,就像大多数其他Kotlin代码编写的那样。 并且因为它们被广泛使用,它们得到了广泛的支持:作为Kotlin生态系统的一部分,每个人都受益。

因此,Kotlin支持函数接口,主要是为了与Java. Compared兼容,与一流的函数兼容,它们基本上是一个黑客。 是一个非常巧妙而优雅的黑客,考虑到向后兼容性对Java平台有多么重要,可以说是必要的。但无论如何, 和我怀疑JetBrains希望鼓励人们在可能的情况下优先使用函数类型。

在Kotlin中,您必须显式地请求一些特性,这些特性可以提高Java兼容性,但可能导致更糟的Kotlin代码(例如静态方法的@JvmStatic,或者转换到java.lang.Object以调用notify())--它符合与您还必须显式请求函数接口(通过使用fun interface)的相同模式。

(还请参阅我关于这一主题的先前的回答。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70569535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档