如何在 Kotlin 中创建具有多个接收器的扩展函数?

Ser*_*gey 18 android kotlin extension-function kotlin-coroutines kotlin-context-receivers

我希望我的扩展功能有几个接收器。例如,我希望函数handle能够调用CoroutineScopeIterable实例的方法:

fun handle() {
    // I want to call CoroutineScope.launch() and Iterable.map() functions here
    map {
        launch { /* ... */ }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这可能有效:

fun <T> (Iterable<T>, CoroutineScope).handle() {}
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误:

Function declaration must have a name
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用参数创建函数,但是

单个函数是否可以有多个接收器以及如何在没有参数的情况下做到这一点?

Ser*_*gey 24

在 Kotlin 版本1.6.20中,有一个名为Context receiveers 的新功能。这是上下文接收器的第一个原型。此功能允许通过将上下文接收器添加到其声明中来使函数、属性和类依赖于上下文。有一个新的语法。在函数声明前面,我们可以指定调用该函数所需的上下文类型列表。上下文声明执行以下操作:

  • 它要求所有声明的上下文接收器作为隐式接收器出现在调用者的作用域中。
  • 它将声明的上下文接收器带入隐式接收器的主体范围。

具有上下文接收器的解决方案如下所示:

context(CoroutineScope)
fun <T> Iterable<T>.handle() {
    map {
        launch { /* ... */ }
    }
}

someCoroutineScope.launch {
    val students = listOf(...)
    students.handle()
}
Run Code Online (Sandbox Code Playgroud)

在 中context(CoroutineScope)我们可以声明多种类型,例如context(CoroutineScope, LogInterface)

由于上下文接收器功能是一个原型,因此要启用它,请-Xcontext-receivers在应用程序的build.gradle文件中添加编译器选项:

apply plugin: 'kotlin-android'
android {
    //...
    kotlinOptions {
        jvmTarget = "11"
        freeCompilerArgs += [
                "-Xcontext-receivers"
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)