提问人:Alraj 提问时间:11/2/2023 最后编辑:Alraj 更新时间:11/3/2023 访问量:51
Kotlin 协程的 block.startCoroutine() 是如何工作的?
How does Kotlin Coroutine's block.startCoroutine() works?
问:
我正在阅读 KEEP 中的协程提案。我在协程生成器部分遇到了这段代码。
fun launch(context: CoroutineContext = EmptyCoroutineContext, block: suspend () -> Unit) =
block.startCoroutine(Continuation(context) { result ->
result.onFailure { exception ->
val currentThread = Thread.currentThread()
currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, exception)
}
})
startCoroutine
是 Function Type 的扩展函数(suspend () -> T)
**
* Starts a coroutine without a receiver and with result type [T].
* This function creates and starts a new, fresh instance of suspendable computation every time it is invoked.
* The [completion] continuation is invoked when the coroutine completes with a result or an exception.
*/
@SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST")
public fun <T> (suspend () -> T).startCoroutine(
completion: Continuation<T>
) {
createCoroutineUnintercepted(completion).intercepted().resume(Unit)
}
我想知道该函数如何执行它正在扩展的函数。因为我在此代码中没有看到任何内容。startCoroutine()
block
this()
createCoroutineUnintercepted()
也扩展了相同的函数类型,但那里没有源代码实现。
@SinceKotlin("1.3")
public expect fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T>
): Continuation<Unit>
询问 ChatGPT 没有带来任何答案。它说
当您调用 时,您实际上是在启动块的执行。
block.startCoroutine(...)
尝试实现一个简单的函数类型扩展示例,但似乎不起作用。
谁能告诉我这个扩展函数类型是如何工作的?
编译器在暂停函数方面也对此做了什么魔法吗?
答:
我想知道 startCoroutine() 函数如何执行它正在扩展的函数 block。因为我在此代码中没有看到任何this()。
请记住,它隐式地存在于整个函数主体的上下文中,因此对 类型的函数或属性(包括扩展)的任何调用都可以在不指定 .所以在实践中,实现就像是写成的:this
this
this.
startCoroutine()
this.
public fun <T> (suspend () -> T).startCoroutine(
completion: Continuation<T>
) {
this.createCoroutineUnintercepted(completion).intercepted().resume(Unit)
}
因此,正如你所看到的,接收器被简单地传递给(因为正如你所指出的,它确实具有相同的接收器类型)。现在,当然,这只是将问题推到另一个函数上。(suspend () -> T)
createCoroutineUnintercepted
但是那里没有源代码实现。
事实上,两者都是 Kotlin 编译器识别和转换的特殊函数(称为内部函数)。这就是它们位于 kotlin.coroutines.intrinsics
包中的原因。它们是语言提供的基本构建块,以便构建更用户友好的框架(例如 Kotlinx 协程库)。createCoroutineUnintercepted
suspendCoroutineUninterceptedOrReturn
我推荐这篇博文来了解什么是基本语言原语,以及我们如何从中构建像 Kotlinx 协程这样的框架: https://blog.kotlin-academy.com/kotlin-coroutines-animated-part-1-coroutine-hello-world-51797d8b9cd4
除了协程的 KEEP 之外,您可能还会发现以下详细的技术文档也很有用: https://github.com/JetBrains/kotlin/blob/master/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutines-codegen.md
尝试实现一个简单的函数类型扩展示例,但似乎不起作用。
关于这个,你只是打印了(使用模板语法),但你没有调用它。您可以在代码中添加括号以使其正常工作(为此,您需要在字符串模板中添加大括号)。因此,只需替换为,它实际上会调用它并打印您期望的内容:this
$this
$this
${this()}
inline fun (() -> Int).start() {
println("start received ${this()}")
}
fun launch(block: () -> Int) {
block.start()
}
fun main() {
launch {
1
}
}
评论
$this
block.startCoroutine()
评论
createCoroutineUnintercepted
createCoroutineUnintercepted
expect
expect