多类型对象表达式中的 Lambda
Lambda in multiple type object expression
我得到了一个 class Foo
可以做一些 work()
:
open class Foo() {
fun work(x: T) {
// Effects taking place here
}
}
我还(但由其他人)提供了一种方法 useJob()
,它使用具有单一方法 doJob()
.
的接口类型 Bar
的对象
fun useJob(bar: Bar)
interface Bar {
fun doJob(x: T)
}
事实证明 Foo.work()
完成了 useJob()
期望的工作。但是,为了让 useJob()
调用 work()
,我需要这样写:
useJob(object : Foo(), Bar { fun doJob(x: T) { work(x) } })
有没有办法使用 lambda 代替这个 blob?
编辑:@jrtapsell 评论让我意识到 Foo 实际上是开放的。
这是一个问题,useJob
需要一个接口而不是直接的函数类型。这样你只能做:
val bar = object : Bar {
override fun doJob(x: String) = Foo().work(x)
}
useJob(bar)
实现此目的的最简单方法是使用创建 Bar 实例并接受函数调用的工厂方法:
fun job(func: (Param) -> Unit) : Bar = object: Bar {
override fun doJob(x: Param) = func(x)
}
那么你可以使用
useJob( job { Foo().work(it) } )
如果在Java中定义了Bar
,你可以写成
useJob { Foo().work(x) }
或
val foo = Foo()
useJob { foo.work(x) }
避免每次都构造 Foo()
以防 useJob
多次调用其参数。
但是
在不将 Bar
移动到 Java 的情况下,我会采用 joecks 的解决方案或定义 useJob
的重载(可能作为扩展方法)。哪个更好取决于您拥有多少种方法,例如 useJob
以及每种方法的用途。
你可以这样做:
// 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 对象的代码,但它会清理调用站点。
我得到了一个 class Foo
可以做一些 work()
:
open class Foo() {
fun work(x: T) {
// Effects taking place here
}
}
我还(但由其他人)提供了一种方法 useJob()
,它使用具有单一方法 doJob()
.
Bar
的对象
fun useJob(bar: Bar)
interface Bar {
fun doJob(x: T)
}
事实证明 Foo.work()
完成了 useJob()
期望的工作。但是,为了让 useJob()
调用 work()
,我需要这样写:
useJob(object : Foo(), Bar { fun doJob(x: T) { work(x) } })
有没有办法使用 lambda 代替这个 blob?
编辑:@jrtapsell 评论让我意识到 Foo 实际上是开放的。
这是一个问题,useJob
需要一个接口而不是直接的函数类型。这样你只能做:
val bar = object : Bar {
override fun doJob(x: String) = Foo().work(x)
}
useJob(bar)
实现此目的的最简单方法是使用创建 Bar 实例并接受函数调用的工厂方法:
fun job(func: (Param) -> Unit) : Bar = object: Bar {
override fun doJob(x: Param) = func(x)
}
那么你可以使用
useJob( job { Foo().work(it) } )
如果在Java中定义了Bar
,你可以写成
useJob { Foo().work(x) }
或
val foo = Foo()
useJob { foo.work(x) }
避免每次都构造 Foo()
以防 useJob
多次调用其参数。
但是
在不将 Bar
移动到 Java 的情况下,我会采用 joecks 的解决方案或定义 useJob
的重载(可能作为扩展方法)。哪个更好取决于您拥有多少种方法,例如 useJob
以及每种方法的用途。
你可以这样做:
// 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 对象的代码,但它会清理调用站点。