Go 语言是原生支持并发编程的, 而 Channel 正是 Go 语言中实现并发不可或缺的类型, 一起来学习一下吧.
什么是 channel
我们知道 gotoutine 是 Go 语言中的并发执行单元, 我们可以创建多个 goroutine 实现程序的并发, 而 goroutine 之间的通讯机制则由 channel 来实现.
channel 是 Go 语言中的一种特殊类型, 我们可以声明一个 channel 可以发送的类型, 然后通过向 channel 发送或接收值到达通讯的目的.
channel 的创建
使用关键字 chan 后跟一个可发送的数据类型, 这样就可以声明一个 channel 变量, 如下所示
var ch chan int
channel 是引用类型, 因此刚声明的 channel 而未初始化的变量初值是 nil, 向未初始化的 channel 类型发送数值, 会引发 panic 错误, 可以使用 make 方法初始化 channel: 如下所示
ch = make(chan int)
经过 make 方法初始化的 channel, 会引用底层的数据结构, 相同类型的 channel 可以进行相等比较, 如果引用相同的底层结构, 则为相等. 所有的 channel 类型都可以跟 nil 比较.
发送与接收操作
channel 的作用便用于通讯的, 所以对 channel 有两个操作, 发送和接收, 在一个 gotoutine 发送数值, 在另一个 goroutine 接收数值, 达到通信中共享内存的目的.
- package main
- import "fmt"
- func main() {
- ch := make(chan int)
- go func() {
- for i := 0; i < 10; i++ {
- ch <- i
- }
- close(ch)
- }()
- for {
- x ,ok := <- ch
- if !ok{
- break
- }
- fmt.Println(x)
- }
- }
在上面的例子中, 我们使用匿名函数创建了一个 gotourine, 在其中向 ch 发送 10 个数值, 并发主 goroutine 中接收, 发送完毕之后, 可可使用 close() 函数关闭 channel.
注意, 如果向已关闭的 channel 发送数值, 会引发 pannic 错误. 如果从已关闭的 channel 中接收值, 则会一直收该数据类型的零值, Go 语言中无法判断 channel 是否关闭, 但可以接收第二个 bool 类型的值来判断是否获取到有效的值, 在上面的例子, 使用 Ok 来表示这个值.
来源: https://juejin.im/post/5c94e6d4e51d453eb46102de