Kotlin 协程将
delay
定义为带有 suspend
关键字的挂起函数,因此
delay
作为 main
的直接子语句不是
允许,因为 main
不是暂停函数delay
称为 runBlocking
或 launch
的子级是允许的,因为那些
函数创建一个协程作用域。编译器如何知道这一点?
suspend
关键字是语言本身的一部分,而 runBlocking
、launch
和协程作用域的概念是通过 kotlinx.couroutines
库添加的。由于上面概述的语法检查可能不依赖于特定的实现,那么它是如何工作的?
请记住,在大多数情况下,如果我们创建新的“范围”或“块”代码,因此我们使用
{ ... }
,例如:
listOf(1).forEach { ... }
runCatching { ... }
run { ... }
然后从技术上讲,我们调用一个向其传递 lambda 的函数。我们调用的函数指定了我们传递的 lambda 的类型。例如,
runCatching()
定义为:
public inline fun <R> runCatching(block: () -> R): Result<R> {
现在,让我们看看
runBlocking()
:
public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
您看到
block
参数的差异了吗?它被标记为suspend
。这意味着 runBlocking()
希望我们向它传递一个挂起 lambda,这样编译器就可以知道我们处于挂起上下文中。
请阅读更多信息:高阶函数和 lambda