为什么在Kotlin中使用方法引用来暂停函数是不可能的?
我有一个Job
实例列表,我想在启动后的某个时候取消。 这看起来如下:
val jobs = arrayListOf<Job>() //launch and add jobs... jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion
不幸的是,这里不可能使用方法引用。 原因: cancelAndJoin
是一个suspend
函数,因为编译器抱怨:
jobs.forEach (Job::cancelAndJoin)
“错误:(30,24)Kotlin:不支持[可调参考暂停功能]”
为什么这不工作? (fyi代码在另一个协程中执行)
基本上,支持这一点需要额外的语言设计部分,而不是简单地与协程捆绑在一起。
为什么它不平凡? 因为当你使用一个普通函数的可调用引用(例如String::reversed
,你会得到类似于KFunction1<String, String>
。 如果你可以使用suspend
功能,你会得到什么?
如果它是相同的KFunctionN<...>
,那么存在一个显而易见的问题,即可以在需要普通函数的地方传递它,并违反suspend
函数只能在协程中调用的规则(编译器将其转换呼叫站点)。
所以,这应该是更具体的东西。 (我目前只是猜测,没有任何实际的设计尝试的想法)例如,它可能是一个SuspendKFunctionN<...>
,它的invoke(...)
是暂停函数,或者它可能(不太可能)是一个特殊的符号,只有在需要suspend (T) -> R
情况下才能传递函数引用,但无论如何,这样的特性需要彻底的设计才能成为未来的保证。
那么暂停功能只能在协同程序或其他内部暂停功能中运行。 如果你的代码在协程里面运行,但是你的控制乐趣不知道,你应该用suspend关键字来标记它。
例如:
suspend fun runJobs(){ val jobs = arrayListOf<Job>() //launch and add jobs... jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion }