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也是阻塞的。

未完待续

相关推荐