Go 中 channel range 的深度理解
Posted 风云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go 中 channel range 的深度理解相关的知识,希望对你有一定的参考价值。
我们来看下两端代码:
代码段1
func main() {
channels := make([]chan int, 10)
for i := 0; i < 10; i++ {
go func(ch chan int) {
time.Sleep(time.Second)
ch <- 1
}(channels[i])
}
for ch := range channels {
fmt.Println("Routine ", ch, " quit!")
}
fmt.Println("结束")
}
猜想下这上面会打印什么结果。
代码段2
func main() {
ch := make(chan int, 10)
for i := 0; i < 10; i++ {
go func() {
ch <- i
}()
}
for range ch {
<-ch
}
fmt.Println(1111)
}
猜想下代码2会打印什么结果。
自己可以运行下,
代码段1会正常运行, 代码段2会死锁, 纳尼,不一样吧,的确就是不一样。
请注意:代码段1 channels 是一个切片类型哦。
####总结一下:
channel 支持 for range 的方式进行遍历,需要注意两个细节。
1.在遍历时,如果 channel 没有关闭,则回出现 deadlock 的错误。
2.在遍历时,如果 channel 已经关闭,则会正常遍历数据,遍历完后,就会退出遍历。
3.对于nil channel,无论收发都会被阻塞。
4.写完 chan 之后一定要关闭close chan,否则主协程读的时候,会发生被阻塞。
select语句中除default外,每个case操作一个channel,要么读要么写。
select语句中除default外,各case执行顺序是随机的。
select语句中如果没有default语句, 则会阻塞等待任一case。
select语句中读操作要判断是否成功读取,关闭的channel也可以读取.
遍历 chan 与 遍历切片类型是不一样的。
以上是关于Go 中 channel range 的深度理解的主要内容,如果未能解决你的问题,请参考以下文章