Select onReceiveOrClosed:已恢复

Select onReceiveOrClosed:已恢复,select,kotlin,kotlin-coroutines,kotlinx.coroutines.channels,Select,Kotlin,Kotlin Coroutines,Kotlinx.coroutines.channels,采取以下方案: package example import kotlinx.coroutines.InternalCoroutinesApi import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.runBlocking import kotlinx.coroutines.selects.select @InternalCoroutinesApi fun main() { runBlocking {

采取以下方案:

package example

import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.selects.select

@InternalCoroutinesApi
fun main() {
    runBlocking {
        val chan = Channel<Unit>()
        chan.close()
        select<Unit> {
            println("Register onReceiveOrClosed.")
            chan.onReceiveOrClosed {
                println("Selected value $it.")
            }
        }
        println("Done.")
    }
}
我希望只看到一行
所选值关闭(null)
,并且我不希望看到任何异常(当然,如果给定给
onReceiveOrClosed
的块执行了两次,那么异常是有意义的)

我对
onReceiveOrClosed
的理解是否不正确,或者这是
onReceiveOrClosed
的错误


我正在使用Kotlin1.3.50和
kotlinx协同程序核心:1.3.1
。这里有一个完整的例子:。

我想这是因为当你调用
select
时,频道已经关闭了。如果您添加一些延迟,它将正常工作:

@InternalCoroutinesApi
fun main() {
    runBlocking {
        val chan = Channel<Unit>()
        launch {
            chan.close()
        }
        select<Unit> {
            println("Register onReceiveOrClosed.")
            chan.onReceiveOrClosed {
                println("Selected value $it.")
            }
        }
        println("Done.")
    }
}

// prints
// Register onReceiveOrClosed.
// Selected value Closed(null).
// Done.
@InternalCoroutinesApi
主要内容(){
运行阻塞{
val chan=频道()
发射{
陈(完)
}
挑选{
println(“接收时注册或关闭”)
chan.on接收或关闭{
println(“选定值$it.”)
}
}
println(“完成”)
}
}
//印刷品
//在接收时注册或关闭。
//所选值已关闭(空)。
//完成了。

我不确定这是一个bug还是有意的行为

我不知道。确保频道没有关闭是可行的,但在大多数情况下,你不能保证这一点。如果onReceiveOrClosed真的是这样工作的,那么它的实用性将非常有限。它是一个实验性的API,所以它可能包含问题,并且可能会像一个bug一样被返工。
@InternalCoroutinesApi
fun main() {
    runBlocking {
        val chan = Channel<Unit>()
        launch {
            chan.close()
        }
        select<Unit> {
            println("Register onReceiveOrClosed.")
            chan.onReceiveOrClosed {
                println("Selected value $it.")
            }
        }
        println("Done.")
    }
}

// prints
// Register onReceiveOrClosed.
// Selected value Closed(null).
// Done.