1

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

我虽然唯一的规则是它的定义具有独特的功能,但是我陷入了以下问题:

我有这个Java接口

public interface ToolbarFragmentCallBack {
    void onNavigationClick();
}

从 java 类调用:

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

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

科特林 (1):

addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
            presenter.onClickNavigationToolBar()
}

爪哇 (2):

addToolBar(R.id.toolbar_fragment, definition.getTitle(), false, () -> {
            activity.onBackPressed();
        });

但是,我最近将接口迁移到了 Kotlin:

interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

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

类型不匹配:推断类型为 () -> Unit 但 ToolbarFragment.ToolbarFragmentCallBack!预计

4

1 回答 1

5

编辑:

现在可以使用 Kotlin 1.4。

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

fun interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
    presenter.onClickNavigationToolBar()
}

老答案:

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

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

但是,新版本 1.4 将改变这种情况(请参阅Kotlin 1.4 中的预期内容):

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

于 2019-12-30T20:23:33.477 回答