通过示例深度理解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,否则主协程读的时候,会发生被阻塞。
5.已关闭的Channel(有缓冲的),如果继续读数据,得到的是零值(对于int,就是0), 如果没有关闭,读不到数据了。
- select语句中除default外,每个case操作一个channel,要么读要么写。
- select语句中除default外,各case执行顺序是随机的。
- select语句中如果没有default语句, 则会阻塞等待任一case。
- select语句中读操作要判断是否成功读取,关闭的channel也可以读取.
遍历 chan 与 遍历切片类型是不一样的。
以上就是Go channel range使用示例深度理解的详细内容,更多关于Go channel range的资料请关注脚本之家其它相关文章!
相关文章
详解golang避免循环import问题(“import cycle not allowed”)
这篇文章主要给大家介绍了关于golang中不允许循环import问题("import cycle not allowed")的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧2018-08-08golang使用viper加载配置文件实现自动反序列化到结构
这篇文章主要为大家介绍了golang使用viper加载配置文件实现自动反序列化到结构示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-08-08
最新评论