我正在研究将协程代码作为launch
的block: suspend CoroutineScope.() -> Unit
协程生成器。我们通常将代码作为lambda传递。但是,我想知道如何将此函数作为显式参数传递给启动函数。
coroutineScope {
launch(block = ::myFunction)
}
suspend fun CoroutineScope.myFunction(): Unit {
// coroutine code
}
它给出以下错误
Type mismatch.
Required:
suspend CoroutineScope.() → Unit
Found:
KSuspendFunction0<Unit>
我想念的是什么?
这种方式呢?
coroutineScope {
launch(block = myFunction())
}
fun myFunction(): suspend CoroutineScope.() -> Unit = {
for(i in 3 downTo 1) {
println("$i")
delay(1000)
}
}
我多次测试了这些行为,这是我得到的:
功能参考实际上变为suspend () -> Unit
,而不是suspend CoroutineScope.() -> Unit
。这是因为它的构建方式,例如,如果使用
fun A.fun(): B {}
val myFun: (A) -> B = A::fun
此接收者更改为一个参数,但是如果使用不明确的coroutineContext(导致性能下降),则在挂起函数的情况下不通过CoroutineScope(导致性能下降),因此覆盖了它在coroutineContext中构建Job的方式,以便获得更好的堆栈跟踪和优化。
我现在为降低性能问题所能做的最好的事情就是像这样手动包装并调用该函数:
coroutineScope {
launch{ myFunction() }
}
suspend fun CoroutineScope.myFunction(): Unit {
// coroutine code
}