在 Kotlin 中,Coroutine 和 Continuation 这两个术语有什么区别?

In Kotlin, what's the difference between the terms Coroutine and Continuation?

这两个术语似乎可以互换使用。然而,似乎也有一些差异,我正在努力指出。有区别吗?

协程是轮流执行任务然后挂起以将控制权交给组中的其他协程并恢复任务的过程。

Continuation 是控制程序流程的堆栈,允许它跳到程序的不同部分。您可以使用它来控制流程,包括协程,如全局 switch.

没错,这两者关系密切。要恢复协程,您实际上调用 continuation.resume().

每个协程都有其关联的延续对象。实际上,除了那个对象你什么都不需要,它包含协程的完整状态。

在某种程度上,Kotlin 使用 "coroutine" 也包含了协程上下文,这让协程知道如何准确地挂起自己,挂起时在哪里保持继续,以及如何恢复(调度)它稍后。但是您也可以使用 Unconfined 协程上下文,这几乎和根本没有上下文一样好,并且可以完全控制恢复,只保留继续对象:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

var continuation: Continuation<Unit>? = null

fun main(args: Array<String>) {
    GlobalScope.launch(Dispatchers.Unconfined) {
        println("Suspending")
        suspendCoroutine<Unit> { cont ->
            continuation = cont
        }
        println("Resumed!")
    }
    println("After launch")
    continuation!!.resume(Unit)
    println("After continuation.resume(Unit)")
}

在这里您可以看到我们重现了整个挂起-恢复场景,只保留了 Continuation 对象。

我的结论是,由于 Kotlin 协程设计的特点(特别是 stackless),[=26= 的概念之间存在模糊界限] 和 "continuation".