DSL,使用接收者作为参数的 lambda 扩展接口方法

DSL, extending an interface method with a lambda with receiver as argument

我有以下接口,其函数接受与接口本身具有相同类型接收器的 lambda:

interface WebhookEventInterface<T> {

    operator fun invoke(block: WebhookEventInterface<T>.() -> Unit) {..}
}

现在我想用另一个接口扩展这个接口,在前一个接口之上提供额外的 capabilities/features,例如:

interface PushPullRequestFeatures<T> : WebhookEventInterface<T> {

    override operator fun invoke(block: PushPullRequestFeatures<T>.() -> Unit) {..}
}

当然,编译器会抱怨,因为 PushPullRequestFeatures 中的函数签名与他的超级 invoke 方法存在函数签名冲突,并且 override 没有覆盖任何内容。

如何在提供相同类型的接收器时覆盖 PushPullRequestFeatures 中超级 WebhookEventInterfaceinvoke 方法?

在 Kotlin 中,您根本无法(据我所知)在重写时更改参数类型,因此您也无法以这种特定方式更改它们。

你可以做的是将接收者类型变成另一个类型参数:

interface WebhookEventInterface<T, out W : WebhookEventInterface<T, W>> {
    operator fun invoke(block: W.() -> Unit) { ... }
}

interface PushPullRequestFeatures<T> : WebhookEventInterface<T, PushPullRequestFeatures<T>> {
    override operator fun invoke(block: PushPullRequestFeatures<T>.() -> Unit) { ... }
}

(如果您不 override,接收器类型无论如何都会是 PushPullRequestFeatures<T>,因为这正是 W 在这里。)