为什么具有无限缓冲通道的生产者不会 return 或 return 来自通道的无效数据?

Why the producer with unlimited buffered channel doesn't return or return invalid data from channel?

看看这个采纳了example from official Kotlin documentation:

package com.example

import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>) = runBlocking {
    val producer = produce {
        for (x in 1..5) send(x)
    }

    for (i in producer) {
        println(i)
    }

    println("Done!")
}

如果我 运行 它将打印:

1
2
3
4
5
Done!

如您所见,默认情况下使用无缓冲通道。让我们将其更改为缓冲通道:

package com.example

import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>) = runBlocking {
    val producer = produce(capacity = Channel.UNLIMITED) {
        for (x in 1..5) send(x)
    }

    for (i in producer) {
        println(i)
    }

    println("Done!")
}

如果我运行它几次它会打印:

1
Done!

2
Done!

或者只是

Done!

我假设生产者会将数据放入缓冲通道并且 for 循环将从中读取数据直到它可以完成(即,如果通道中存在数据或通道中不存在数据,它将读取关闭)。因此,我认为 for 循环应该从缓冲通道中读取所有数据,即使它已关闭。我说得对吗?

谁能解释一下为什么缓冲通道会导致生产者出现这种奇怪的行为?是错误吗?

P.S.

Kotlin 团队已确认这是一个错误,并opened an issue针对此问题作出回应。

问题的描述提到它只出现在 produce 构建器中并提供了一个解决方法,基本上是该便利构造的内联代码:

val producer = Channel<Int>(1)
launch(coroutineContext) {
    for(i in 1..2) {
        producer.send(i)
        println("Sent: $i")
    }
    producer.close()
}