【问题标题】:Kotlin - Interfaces as Trailing LambdasKotlin - 作为尾随 Lambda 的接口
【发布时间】:2019-12-30 19:53:18
【问题描述】:

使接口能够用作尾随 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()
}

Java (2):

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

不过,我最近将界面迁移到了 Kotlin:

interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

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

类型不匹配:推断类型为 () -> 单位但 ToolbarFragment.ToolbarFragmentCallBack!预料之中

【问题讨论】:

  • 哦,谢谢,@jsamol,我不知道它只适用于 Java 接口。你想把它作为答案发布,以便我可以选择它吗?

标签: java kotlin lambda interface


【解决方案1】:

编辑:

现在可以使用 Kotlin 1.4。

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

fun interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

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

旧答案:

目前 Kotlin 仅支持 Java 接口的 SAM 转换 (见docs):

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

但是,随着新版本 1.4 的出现,这种情况即将发生变化(请参阅 What to Expect in Kotlin 1.4):

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

【讨论】:

    猜你喜欢
    • 2019-10-03
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    相关资源
    最近更新 更多