Go语言 chan的剖析
什么是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也是阻塞的。
未完待续