为什么在Kotlin中使用`suspend`函数的方法引用是不可能的?

时间:2017-11-10 20:58:01

标签: kotlin coroutine kotlinx.coroutines

我有一个val jobs = arrayListOf<Job>() //launch and add jobs... jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion 个实例的列表,我希望在启动后的某个时刻取消它们。这看起来如下:

cancelAndJoin

不幸的是,这里不可能使用方法参考。原因是:suspendjobs.forEach (Job::cancelAndJoin) 函数,正如编译器抱怨的那样:

$#

&#34;错误:(30,24)Kotlin:不支持[可暂停函数的可调用引用]&#34;

为什么这不起作用?

2 个答案:

答案 0 :(得分:8)

基本上,支持这一点需要额外的语言设计部分,而不是简单地与协同程序捆绑在一起。

为什么这不重要?因为当您采用普通函数的可调用引用时,例如String::reversed,你得到类似KFunction1<String, String>的内容。如果您可以使用suspend函数执行相同的操作,那么您期望获得什么?

如果它是相同的KFunctionN<...>,则会出现一个明显的问题,即您可以将其传递到预期普通函数的位置并调用它,这违反了{{1}的规则函数只能在协同程序内部调用(编译器转换其调用站点)。

所以,它应该是更具体的东西。 (我目前只是推测,不知道实际的设计尝试)例如,它可能是suspend,其SuspendKFunctionN<...>是暂停功能,或者它可能(不太可能) )是一个特殊的符号,仅用于传递预期invoke(...)的函数引用,但无论如何,这样的特性需要彻底的设计才能面向未来。

答案 1 :(得分:1)

这些帮助程序目前在Kotlin Standard库中缺少,但是您可以实现自己的帮助。

例如:

suspend fun <T> Iterable<T>.forEachAsync(action: suspend (T) -> Unit): Unit {
    val list = this.map { e ->
        async(...) {
            action(e)
        }
    }
    list.forEach { it.await() }
}

但是,现在传递给异步的上下文取决于您的服务使用的线程模型(即,您要执行多线程还是将所有内容保留在单个线程中)。