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对象,但它清理呼叫站点。

Interesting Posts