kotlin 使用不同的调度接收器组合块

flseospp  于 2022-12-13  发布在  Kotlin
关注(0)|答案(1)|浏览(130)

设定:

interface AProvider {
    fun getA(): String
}

interface BProvider {
    fun getB(): String
}

fun a(block: AProvider.() -> Unit) {}
fun b(block: BProvider.() -> Unit) {}

这样,我就可以如下嵌套这两个函数

val x = a { b { getA(); getB() } }

现在我想把这个特定的模式抽象成一个更高级别的函数,这样我就可以传递内部块,并在其中调用getA()getB(),例如:

val y = { l: ??? -> a { b(l) } }

val z = y { getA(); getB() }

问题是

  • y的定义下,这是可能的吗?
  • 如果是,l的类型应该是什么?
  • 如果没有,是否有其他的定义可以让我在lambda中访问多个调度接收器?

注意:这与我的other SO question有关

iugsix8n

iugsix8n1#

你可以用context receivers来实现这一点,它允许你为一个lambda指定多个接收者。y的类型可以是:

(context(AProvider, BProvider) () -> Unit) -> Unit

也就是说,一个函数接受另一个函数作为参数,并返回Unit。它接受的函数参数也返回Unit,但将AProviderBProvider作为其上下文接收方。

val y: (context(AProvider, BProvider) () -> Unit) -> Unit = { l -> 
    a { b { l(this@a, this@b) } } 
}

val z = y { getA(); getB() }

注意,当我们调用l时,我们传递上下文接收器this@athis@b,就好像它们是常规参数一样。
这使得z也变成了Unit,这有点奇怪。y返回的是a返回的内容,所以也许您并不希望a返回Unit

相关问题