在 Kotlin 中组合协程上下文的目的是什么?

What's the purpose of combining coroutine contexts in Kotlin?

https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html#combining-context-elements

官方文档说可以合并一些coroutine context,但是这样做的目的是什么,有什么作用呢? 这是否意味着协程的生命周期仅限于两种上下文?

我认为您混淆了 CoroutineContextCoroutineDispatcher(可能还有 CoroutineScope)。 Dispatcher只是一种Context。其他人可以是例如。 JobCoroutineNameCoroutineExceptionHandler。您可以组合其中的多个 - 例如。设置调度程序和错误处理程序 - 但每种类型只有一个。

组合多个调度器没有意义,只会应用最后一个。

我在 KotlinConf 2019 中发现 the talk Coroutines! Gotta catch 'em all! by Florina Muntenescu & Manuel Vivo 很好地解释了其中的一些内容。

I can combine some coroutine contexts, but what's the purpose of doing so and what's the effect?

协程上下文基本上是一个不可变的映射。当您组合两个不可变映射时,您会得到一个包含构成映射的所有键的映射。显然,如果两个映射都包含给定的键,则生成的映射不能包含它两次。相反,右侧地图优先。

映射范式的一个细微变化是您没有将(键,值)对放入上下文中,而是您放置的每个值都已经有一个与之关联的键。这就是每个上下文元素本身已经是上下文的原因。

例如,这是两个成熟的上下文:

val ioCtx = Dispatchers.IO
val jobCtx = Job()

您可以组合它们:

val ioAndJob = ioCtx + jobCtx

您可以通过键访问一个元素:

val job = ioAndJob[Job]

您可以将上下文与冲突键结合起来:

val defaultAndJob = ioAndJob + Dispatchers.Default

Does that mean the coroutine's lifecycle is confined to both contexts?

协程上下文不限制协程生命周期。需要一些外部代理来取消协程上下文中的作业。您可能将此与 CoroutineScope 混淆了,后者负责处理此问题。 CoroutineScope 只是一个具有单个 属性、coroutineContext 的对象,但是由于 launchasync 等协程构建器将其作为接收者,因此它使它易于构建可集中取消的协程层次结构。