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)