首页 > 解决方案 > DSL,使用带有接收器作为参数的 lambda 扩展接口方法

问题描述

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

interface WebhookEventInterface<T> {

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

现在我想用另一个接口扩展这个接口,在前一个接口的基础上提供额外的功能/特性,比如:

interface PushPullRequestFeatures<T> : WebhookEventInterface<T> {

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

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

如何在提供相同类型的接收器时覆盖invokesuper WebhookEventInterfacein的方法?PushPullRequestFeatures

标签: kotlingenericslambdainterfacereceiver

解决方案


在 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就是这里的内容。)


推荐阅读