共计 981 个字符,预计需要花费 3 分钟才能阅读完成。
什么是 channel?
channel 是 goroutine 之间互相通信的工具。具体点的说法,channel 是一种通信管道,能够把数据放入管道,也能从管道中读出数据。一个 goroutine 把数据放入 chan,然后另外一个 goroutine 可以从 chan 里面读出数据。
channel 的使用
Go 语言提供 chan 关键字来创建 channel,一个 channel 只能传递一种数据结构,其他类型的数据是不可以使用该 channel 的。
package main
import “fmt”
func main(){
var c chan int
fmt.Println(c)
}
上面的代码声明了一个可以传递 int 类型的 channel 变量 c, 但是最后会输出 nil,因为 chan 的初始值是 nil。你不可以对一个值为 nil 的 chan 进行操作,你必须使用 make 关键字来创建可用的 chan。
package main
import “fmt”
func main(){
c := make(chan int)
fmt.Printf(“c 的类型是 %T \n”, c)
fmt.Printf(“c 的值是 %v \n”, c)
}
输出结果如下:
c 的类型是 chan int
c 的值是 0xc42008060
我们发现 c 的值似乎是个地址。channel 默认其实是个指针。大部分情况下,你只要把 channel 当做参数在一个 goroutine 里传递给发送函数,另一个 goroutine 也以直接从接收函数里面把 chan 当做参数来使用。
数据读写
go 语言中使用 <- 来传递数据给 channel.
c <- 1
看起来像左箭头,所以很好想象成是把右边的东西送到左边里面去。
<- c
注意,这也是正确的语法,我们从 chan 里面读取了数据,但是并没有使用,不过使用下面这种写法:
var data int
data <- c
这样子,从 c 里面来的数据,就能存到 data 里面去了。也可以简写成下面这种形式
data := <- c
go 语言会自动推导 data 的类型为 int
请注意,上面的操作都会导致阻塞,当 goroutine1 把信息写入 channel 中的时候,当没有人读取这个 channel 数据的时候,gouroutine1 是会阻塞的,直到 gouroutine2 从 channel 里读出数据,gouroutine1 才会取消阻塞。同理:当 goroutine1 没有写入数据到 chan 的时候,goroutine2 也是阻塞的。
未完待续