主要功能:

fun main() = runBlocking {
    val channel = Channel<Int>()
    foo(channel)
    for (y in channel) println(y)
    println("Done!")
}

这是可行的:

fun CoroutineScope.foo(channel: Channel<Int>) {
    launch {
        for (x in 1..5) channel.send(x * x)
        channel.close()
    }
}

这不起作用(它在通道上阻止发送):

suspend fun foo(channel: Channel<Int>) = coroutineScope {
    launch {
        for (x in 1..5) channel.send(x * x)
        channel.close()
    }
}

为什么?

推荐答案

如文件coroutineScope中所述:

该函数在给定块及其所有子协程完成后立即返回

因此,写coroutineScope { launch { something() }}只相当于something(),因为它等待launch的完成.反过来,这意味着只有在循环完成且通道关闭时,您的第二个foo版本才返回.

另一方面,仅使用launch会启动一个异步任务,因此foo()之后的代码可以与其并发工作.

实际上,如果在两种情况下都内联foo(),您将意识到launch-ed协程在第一种情况下由runBlocking的作用域分隔,在第二种情况下由coroutineScope的作用域分隔.

Kotlin相关问答推荐

编译后的JavaFX应用程序立即以静默方式崩溃

为什么Kotlin协程程序即使有延迟也能输出?

Kotlin:将泛型添加到列表任何>

用Quarkus和Reactor重写异步过滤器中的数据流

try 一次性插入多条记录时,JOOQ连接为空错误

Kotlin 插件之间的区别

如何将jooq multiset的结果映射到Hashmap(Java Map)?

如何为 material.Slider 视图创建绑定适配器?

在构造函数中仅注入某些参数

在 Kotlin 中取最后 n 个元素

无法为 retrofit2.Call 调用无参数构造函数

Kotlin中的测试无法访问受保护(protected)的方法

Kotlin not nullable值可以为null吗?

是否在Kotlin中重写enum toString()?

添加抽象的私有getter和公共setter的正确方法是什么?

如何获取Kotlin中变量的名称?

Lint 错误:可疑的相等判断:在 Object DiffUtilEquals 中未实现 equals()

Jetpack Compose 折叠工具栏

在android java类中使用Kotlin扩展

尾随 lambda 语法(Kotlin)的目的是什么?