62

Go语言 chan的剖析

 5 years ago
source link: https://segmentfault.com/a/1190000018607359?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

未完待续


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK