for
循环select
时,如果通道已经关闭会怎么样?如果select
中的case
只有一个,又会怎么样?
select
时,如果其中一个case通道已经关闭,则每次都会执行到这个case。c通道
是一个缓冲为0
的通道,在main
开始时,启动一个协程对c通道
写入10
,然后就关闭掉这个通道。main
中通过 x, ok := <-c
接受通道c
里的值,从输出结果里看出,确实从通道里读出了之前塞入通道的10
,但是在通道关闭后,这个通道一直能读出内容。x, ok := <-c
返回的值里第一个x是通道内的值,ok
是指通道是否关闭,当通道被关闭后,ok
则返回false
,因此可以根据这个进行操作。读一个已经关闭的通道为什么会出现false,可以看我之前的 对已经关闭的的chan进行读写,会怎么样?为什么? 。ok
为false
时,执行c = nil
将通道置为nil
,相当于读一个未初始化的通道,则会一直阻塞。至于为什么读一个未初始化的通道会出现阻塞,可以看我的另一篇 对未初始化的的chan进行读写,会怎么样?为什么? 。select
中如果任意某个通道有值可读时,它就会被执行,其他被忽略。则select
会跳过这个阻塞case
,可以解决不断读已关闭通道的问题。case
的情况下,则会死循环
。case
那样,把通道置为nil
就能解决问题了吗?case
能读到通道里的10
case
能读到通道已经关闭的信息。此时将通道置为nil
case
时main协程会被阻塞,此时整个进程没有其他活动的协程了,进程deadlock
select
中如果任意某个通道有值可读时,它就会被执行,其他被忽略。default
字句,select
将有可能阻塞,直到某个通道有值可以运行,所以select
里最好有一个default
,否则将有一直阻塞的风险。