对于没有初始化的channel进行读写操作将会发生阻塞。main goroutine被阻塞在channel上,导致Go运行时认为出现deadlock状态并抛出panic。
但是nil channel并非一无是处,有时候妙用nil channel可以达到事半功倍的效果。如下示例所示:
func testNilChannel() {
c1, c2 := make(chan int), make(chan int)
go func() {
time.Sleep(time.Second * 5)
c1 <- 5
close(c1)
}()
go func() {
time.Sleep(time.Second * 7)
c2 <- 7
close(c2)
}()
var ok1, ok2 bool
for {
select {
case x := <-c1:
ok1 = true
fmt.Println(x)
case x := <-c2:
ok2 = true
fmt.Println(x)
}
if ok1 && ok2 {
break
}
}
fmt.Println("program end")
}
此测试程序目的是依次输出5和7两个数字后退出,但是实际输出结果是在输出5之后,程序输出了许多0后才输出7并退出。简单分下下以上代码运行过程:
- 前5s,select一致处于阻塞状态
- 第5s,c1返回5后被关闭,select语句的case x := <-c1分支被选出执行,程序输出5,回到for循环并开始新一轮select
- c1被关闭,由于一个一杯关闭的channel接收数据将永远不会被阻塞,所以新一轮select又将case x :=