如果没有默认值,为什么可以在不提供 CoroutineContext 的情况下调用 runBlocking ?

cae*_*eus 8 kotlin kotlin-coroutines

我总是检查我使用的东西的实现。

目前,我使用的注入库不支持可挂起的函数(Koin),因此,仅(即使不鼓励)为了引导应用程序,我有时会使用 runBlocking。

为了拥有更丰富的日志,我用一些信息丰富了协程上下文,但这些信息在大多数上下文更改(launchasyncrunBlocking)中都会丢失。

特别是,考虑到非挂起方法无法访问 CoroutineContext,我非常好奇runBlocking它是从哪里获取的。

你可以runBlocking这样使用:

runBlocking {...}
Run Code Online (Sandbox Code Playgroud)

然而,当我检查它的实现时,它有两个参数:aCoroutineContext和要执行的挂起块。这些参数都没有默认值,那为什么我可以不传递就调用它呢?我真的不明白!

此外,该页面说默认值是,EmptyCoroutineContext但代码文档说了一些有关事件循环的内容。

那我再问一下?为什么我可以在不传递值的情况下调用它,实际的默认值是什么?

bro*_*oot 10

默认情况下,runBlocking()以空的协程上下文开始。

context没有默认值这一事实确实令人困惑和奇怪。我认为(但我不是 100% 确定)这是因为通过 ctrl+单击runBlocking()我们可以实现,所以actual定义。但代码是根据expect声明编译的。我没有找到expect直接在 IntelliJ 中查看声明的简单方法,但可以在这里找到:

public expect fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,context在这个声明中有一个默认值。尽管如此,使用 IntelliJ 时这确实令人困惑。

关于提到的事件循环:是的,runBlocking()创建(或重新使用)事件循环,但我不知道它与协程上下文有何关系。