本系列是阅读 “The Go Programming Language” 理解和记录。
定义
如果说 goroutine 是并发执行的一个 Go program, channel 就是它们之间的连接通道,它提供了 goroutine 之间相互通信的机制。Channel 是有类型的,channel 中使用的 type 称之为 element type,比如 int 类型的 channel 写作为 chan int
。
Go 使用 make 内建函数创建 channel。1
ch := make(chan int)
同 map 一样,一个 channel 引用着 make 创建的底层数据结构上,当把 channel 当做函数参数传递时,实际上是拷贝一份 reference,也就是说函数内部和外部引用的是相同的数据结构,所以在函数内部可以直接修改 channel 的值。同其它 reference type 一样,channel 的 zero value 是 nil。
Channel 是可比较的
Channel 是可比较的,如果两个 channel 的类型相同,它们可以彼此相互比较:
1 | ch01 := make(chan int) |
两个不是 nil 的 channel 比较实际上比较的他们的 reference 是否相同,如果他们都引用同一个 channel,则他们相同:
1 | func main() { |
当然 channel 也可以和 nil 比较,没有初始化的 channel 就是 nil:1
2
3
4var ch02 chan int
if ch02 == nil {
fmt.Println("ch02 is nil")
}
Channel 的基本操作
Channel 有三种基本的操作 send、receive、close。
Send
Channel 支持 send 操作,意思是向 channel 中发送数据,Go 使用 <-
操作符来实现 send:1
ch <- x //send
Send 时 <-
在 channel 右侧。
Receive
Channel 还支持 receive 操作,意思是从 channel 中取出数据,Go 也是使用 <-
操作符来实现 receive:1
x := <- ch //receive
Receive 时 <-
在左侧,如果一个执行 receive 时没有用任何变量来赋值,则该值被抛弃,receive 的这个操作常常被用来做状态同步:
1 | <- ch |
Close
Channel 还支持第三种操作 close
,如果 channel 被 close,表明 channel 不会再 send 任何值了,如果还继续对 channel 执行 receive 操作,当 channel 中的值消耗完毕之后,之后返回的是对应 element type 的 zero value,如果对 channel 执行 send 操作,将会引起 panic:1
2close(ch)
ch <- x // panic
Close 操作常常和 for 语句配合使用,表示一个 channel 不再产生新的值:1
2
3
4
for x := range ch {
fmt.Print(x)
}
Close channel 之后,for 循环将结束。
参考资料
- The Go Programming Language