写点什么

Golang channel 通道

用户头像
escray
关注
发布于: 2021 年 06 月 05 日
Golang channel 通道

极客时间《Go 语言核心 36 讲》学习笔记 07,图片来自网络

10 | 通道的基本操作


Don't communicate by sharing memory; share memory by communicating


通道类型是 Go 语言自带的唯一并发安全的类型,一个通道相当于一个先进先出队列。


元素值从外界进入通道时会被复制,进入通道的是它的副本(复制元素值、放置副本到通道内部);元素值从通道进入外界时会被移动(生成副本、放置副本到接收方、删除通道中的元素值)


非缓冲通道用同步的方式传递数据,缓冲通道使用异步的方式传递数据


对于思考题:


  1. 通道的长度代表缓冲区大小,在缓冲区满的时候,与通道容量相同

  2. 元素值的复制应该是浅表复制


看了一下留言,老师在这里挖了个坑,“Go 语言里面没有深层复制”

11 | 通道的高级玩法


单向通道这个设计,似乎在别的语言中是没有的,有点类似于文件的只读或者只写属性(用于约束 IO 操作),单向通道用于约束其他代码的行为。


单向通道可以用于接口类型申明中的方法定义(参数列表),也可以用在函数声明的结果列表中


而 Go 语言在实现过程中,自动的将双向通道转换为单向通道也减轻了实现时候的负担。


demo24 示例 1 的代码有一点奇怪,我执行的时候通常随机数会生成为 2,不知道什么原因,当然,这个不重要。


看到留言里面 @任性 同学的提示,增加


rand.Seed(time.Now().Unix())
复制代码


就可以解决随机数的问题。


从 demo25 中的示例可以看到,Go 语言 select 语句(与通道连用)和其他语言的 switch 是完全不一样的,我之前对这个部分有一些混淆。


对于思考题:


  1. 如果在 select 语句中发现某个通道已关闭,使用类似 demo24 示例二中的方法,可以判断通道是否已关闭,如果关闭,就是用 break 来结束当前 select。不知道这个是不是屏蔽的意思

  2. 如果 select 语句和 for 语句连用,一方面使用 break 结束当前的 select,另外就是可以设置一个标记为,结束整个 for 循环。


看了一下留言和标准答案,两道思考题似乎都没有做对。


第一个思考题当发现通道关闭的时候,将 chan 赋值为 nil,就可以实现屏蔽。


第二个题目推荐留言中提到了 stackoverflow 的链接,https://stackoverflow.com/questions/25469682/break-out-of-select-loopfor-select break


给出了两种方法,一种是用 return 替换 break,另一种是使用类似于 goto 语句的标签,进行 break


L:  for {    select {    case <-done:      // break      // return      break L    case num := <- numbers:      fmt.Println(num)    }  }
复制代码


比较佩服那些不看留言,也不看看课后答案,直接提问的同学。


不知道为什么,这篇文章留在了草稿箱里,导致我五月日更变成了“七日更”

发布于: 2021 年 06 月 05 日阅读数: 8
用户头像

escray

关注

Let's Go 2017.11.19 加入

Let's Go,用 100 天的时间从入门到入职

评论

发布
暂无评论
Golang channel 通道