Bootstrap

Golang channel 通道

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

10 | 通道的基本操作

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

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

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

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

对于思考题:

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

11 | 通道的高级玩法

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

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

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

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

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

rand.Seed(time.Now().Unix())

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

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

对于思考题:

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

第一个思考题当发现通道关闭的时候,将 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)
    }
  }

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

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