Kotlin - 作为尾随 Lambda 的接口

hta*_*oya 1 java lambda interface kotlin

哪些规则使接口能够用作尾随 lambda参数?

我认为唯一的规则是让它在其定义上具有独特的功能,但是我遇到了以下问题:

我有这个Java接口

public interface ToolbarFragmentCallBack {
    void onNavigationClick();
}
Run Code Online (Sandbox Code Playgroud)

从 Java 类调用:

public void addToolBar(int container, String title, boolean isParent,
                       ToolbarFragment.ToolbarFragmentCallBack callback) {
      //do something
}
Run Code Online (Sandbox Code Playgroud)

它是从 Kotlin 和 Java 文件中调用的:

科特林 (1):

addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
            presenter.onClickNavigationToolBar()
}
Run Code Online (Sandbox Code Playgroud)

爪哇(2):

addToolBar(R.id.toolbar_fragment, definition.getTitle(), false, () -> {
            activity.onBackPressed();
        });
Run Code Online (Sandbox Code Playgroud)

但是,我最近将界面迁移到了 Kotlin:

interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}
Run Code Online (Sandbox Code Playgroud)

现在 **Kotlin (1) ** 实现调用无法编译,并带有消息

类型不匹配:推断的类型是 () -> Unit 但 ToolbarFragment.ToolbarFragmentCallBack!预料之中

jsa*_*mol 5

编辑:

现在可以使用 Kotlin 1.4。

但是请注意,SAM 转换仍然不适用于标准接口,您必须显式声明您的接口为功能接口

fun interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
    presenter.onClickNavigationToolBar()
}
Run Code Online (Sandbox Code Playgroud)

旧答案:

目前,Kotlin 仅支持 Java 接口的 SAM 转换(请参阅文档):

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

但是,这将随着新版本 1.4 发生变化(请参阅Kotlin 1.4 中的期望):

社区要求我们为 Kotlin 类引入对 SAM 转换的支持。[...] SAM 转换目前仅适用于 Java 接口和抽象类。此设计背后的最初想法是为此类用例明确使用函数类型。然而,事实证明,函数类型和类型别名并没有涵盖所有用例,人们经常不得不在 Java 中保留一个接口,只是为了获得 SAM 转换。