我正在为我的项目创建一个DSL,我真的希望能够使用来自多个接收器的fieldmethods而不需要嵌套它们。
例如:
class Foo {
val fooField = "Foo field"
}
class Bar {
val barField = "Bar field"
}
fun main() {
val foo = Foo()
val bar = Bar()
(foo..bar) {
println(fooField)
println(barField)
}
}
取而代之的是:
class Foo {
val fooField = "Foo field"
operator fun invoke(block: Foo.() -> Unit) {
block(this)
}
}
class Bar {
val barField = "Bar field"
operator fun invoke(block: Bar.() -> Unit) {
block(this)
}
}
fun main() {
val foo = Foo()
val bar = Bar()
foo {
bar {
println(fooField)
println(barField)
}
}
}
我曾想过这样的方法:
class Buzz<T1, T2>(
val t1: T1,
val t2: T2
) {
operator fun invoke(function: /* T1 + T2*/ () -> Unit) { // <--- ???
function(/* t1 + t2*/)
}
}
operator fun <T, R> T.rangeTo(r: R): Buzz<T, R> {
return Buzz(this, r)
}
但我能不能以某种方式结合两个接收器而不使用模板?
你不能这样做,因为一个变量不能同时容纳两个对象的引用。
但类似的解决方案可以是使用一对变量,它可以是 关联* 与你的问题。
val foo = Foo()
val bar = Bar()
Pair(foo,bar).apply { // this: Pair<Foo, Bar>
println(first.fooField)
println(second.barField)
}
注意*: 这只是一个建议 it does remove boilerplate by nested lambdas
但另一方面,并没有提供一个解决方法,与此同时。lambda with multiple receivers