Kotlin 中接口的 Lambda 实现

Posted

技术标签:

【中文标题】Kotlin 中接口的 Lambda 实现【英文标题】:Lambda implementation of interface in kotlin 【发布时间】:2018-06-25 09:11:17 【问题描述】:

在 kotlin 中该代码相当于什么,我尝试的似乎没有任何效果:

public interface AnInterface 
    void doSmth(MyClass inst, int num);

初始化:

AnInterface impl = (inst, num) -> 
    //...

【问题讨论】:

【参考方案1】:

您可以使用object expression

所以它看起来像这样:

val impl = object : AnInterface 
    override fun(doSmth: Any, num: Int) 
        TODO()
    

【讨论】:

【参考方案2】:

如果AnInterface 是Java,您可以使用SAM conversion:

val impl = AnInterface  inst, num -> 
     //...

否则,如果接口是Kotlin...

interface AnInterface 
     fun doSmth(inst: MyClass, num: Int)

...您可以使用object 语法匿名实现它:

val impl = object : AnInterface 
    override fun doSmth(inst:, num: Int) 
        //...
    

【讨论】:

为什么 Kotlin 接口没有与 Java 类似的 SAM 转换?这个 AnInterface inst, num -> 是否也可以应用于 Kotlin 接口? 你可以在这里投票赞成这个问题:discuss.kotlinlang.org/t/sam-conversion-on-kotlin-interfaces/… 如果我想将它传递给一个以 AnInterface 作为参数的函数怎么办。我写这个吗? myFun(object : AnInterface override fun doSmth(ints:, num: Int) ... ) 必须有更好的方法!【参考方案3】:

如果您将接口及其实现都重写为 Kotlin,那么您应该删除接口并使用函数类型:

val impl: (MyClass, Int) -> Unit =  inst, num -> ... 

【讨论】:

这是真正的答案......另外两个没有解决 lambda 实现。但是,如果我仍然想使用自己声明的接口(出于可读性原因),是否意味着我不能使用 lambda? @SiraLam 你可以为函数类型声明一个默认变量名:val listener: (name: Class, other: OtherClass) -> Unit @SiraLam 如果您出于可读性的原因想要界面,那么您可能正在遭受原始痴迷。 tl; dr - 不要使用原语作为参数。带有此签名的函数有什么作用? (String) -> String 没有名字,你无法推理。现在,带有这个签名的函数有什么作用? (UserId) -> PhoneNumber - 好吧,唯一合理的实现是通过 ID 查找用户数据,然后取出电话号码并返回它。如果您的函数不采用原语,那么您通常不需要将它们包装在接口中以提高可读性。【参考方案4】:

你也可以这样做,使用@lambda标签


interface AnInterface 
     fun doSmth(inst: MyClass, num: Int)


val impl = AnInterface lambda@inst, num ->
    //..


【讨论】:

以上是关于Kotlin 中接口的 Lambda 实现的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)

在 Kotlin lambda 表达式中覆盖多个接口方法

如何使用 lambda 而不是 kotlin 接口

Kotlin学习与实践 带接收者的lambda及Java的函数式接口

Kotlin lambda学习

如何在kotlin中将lambdas与函数式接口一起使用并直接将lambda分配给var