Lambda在多个类型的对象表达式中
我提供了一个Foo
类来完成一些work()
:
open class Foo() { fun work(x: T) { // Effects taking place here } }
而且我还提供了一个方法useJob()
,它使用了一个方法doJob()
,该方法使用一个doJob()
方法的接口类型Bar
。
fun useJob(bar: Bar) interface Bar { fun doJob(x: T) }
事实证明, Foo.work()
完成了Foo.work()
所期望的工作。 但是,为了使用useJob()
调用work()
,我需要写这样的东西:
useJob(object : Foo(), Bar { fun doJob(x: T) { work(x) } })
有没有办法使用lambda而不是这个blob?
编辑:@ jrtapsell评论让我意识到Foo实际上是开放的。
如果Bar
是用Java定义的,你可以写
useJob { Foo().work(x) }
要么
val foo = Foo() useJob { foo.work(x) }
以避免每次useJob
调用它的参数时构造Foo()
。
但
请注意,此功能仅适用于Java interop; 由于Kotlin具有适当的函数类型,函数自动转换为Kotlin接口的实现是不必要的,因此不受支持。
如果不将Bar
移动到Java,我会使用joecks的解决方案或定义useJob
的重载(可能是扩展方法)。 哪个更好取决于useJob
有多少个方法,每个方法有多少个用途。
那么实现这个最简单的方法就是使用一个工厂方法来创建一个Bar实例并接受一个函数调用:
fun job(func: (Param) -> Unit) : Bar = object: Bar { override fun doJob(x: Param) = func(x) }
那么你可以使用
useJob( job { Foo().work(it) } )
这是一个问题, useJob
直接期待接口而不是函数类型。 这样你只能做到:
val bar = object : Bar { override fun doJob(x: String) = Foo().work(x) } useJob(bar)
你可以这样做:
// Mock class class Param // Provided code open class Foo<T> { fun work(x: T) { // Effects taking place here } } fun useJob(bar: Bar) {} interface Bar { fun doJob(x: Param) } // New code object FooBar: Foo<Param>(), Bar { override fun doJob(x: Param) = work(x) fun use() = useJob(this) } fun x() { FooBar.use() }
它需要更多的代码为FooBar对象,但它清理呼叫站点。