You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套不同调度接收器的Compose代码块:抽象与类型问询

Kotlin多接收器Lambda抽象问题解答

前置代码

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() } }

构想的抽象方式:

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

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

待解答问题

  1. 按上述y的定义是否可行?
  2. 若可行,参数l的类型应是什么?
  3. 若不可行,是否存在其他定义方式可让lambda访问多个调度接收器?

问题解答

  1. 不可行。b函数要求传入的lambda类型是BProvider.() -> Unit,这个lambda的调度接收器只有BProvider,无法直接访问AProvider的getA()方法。而构想中直接把l传给b,l如果要调用getA(),必须同时拥有AProvider的上下文,但当前结构下无法让b的lambda同时持有两个调度接收器的上下文,所以这种定义方式走不通。

  2. 由于第一种方式不可行,此问题无对应答案。

  3. 有三种可行方案实现lambda访问多个调度接收器:

方案一:合并接收器接口

定义一个同时继承AProvider和BProvider的接口,通过代理两个原接收器的方式让lambda能访问两者的方法:

interface ABProvider : AProvider, BProvider

fun ab(block: ABProvider.() -> Unit) {
    a {
        b {
            // 创建代理类,同时代理AProvider和BProvider的实现
            val abProxy = object : ABProvider {
                override fun getA() = this@a.getA()
                override fun getB() = this@b.getB()
            }
            abProxy.block()
        }
    }
}

// 使用示例
val z = ab { getA(); getB() }

方案二:显式传递外部接收器

让lambda接收外部的AProvider作为参数,同时保留BProvider作为自身的调度接收器:

val y = { l: AProvider.(BProvider) -> Unit ->
    a {
        b {
            // 将外部的AProvider和当前的BProvider传给lambda
            this@a.l(this)
        }
    }
}

// 使用示例:lambda中通过this@y访问AProvider,this访问BProvider
val z = y { getA(); this.getB() }

方案三:利用Kotlin上下文接收器(1.6+)

Kotlin 1.6及以上支持上下文接收器特性,可以直接声明lambda需要同时拥有AProvider和BProvider两个上下文:

// 定义需要两个上下文的lambda类型
context(AProvider, BProvider)
typealias ABBlock = () -> Unit

val y = { l: ABBlock ->
    a {
        b {
            // 同时带入AProvider和BProvider的上下文执行lambda
            with(this@a) {
                l()
            }
        }
    }
}

// 使用示例:lambda自动拥有两个上下文,可直接调用两个方法
val z = y { getA(); getB() }

内容的提问来源于stack exchange,提问作者David Kubecka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:15:37