channel入门指南 | 青训营

61 阅读2分钟

引言

在上篇goroutine资源竞争部分,我提出了主线程和协程间的结束问题,由此我们可以引出解决办法channel(管道)

介绍

channel的本质就是一种队列,是一种数据结构。数据在管道中先进先出(FIFO:first in first out)。管道也是有数据类型的,如int类型的channel只能存放int类型的数据。

入门

基本语法:var 变量名 chan 数据类型

  1. channel是引用类型
  2. channel必须make后才能使用。
  3. channel只能放定义的数据类型。

make的使用方法:变量名 = make (chan 数据类型,容量)。channel的容量并不会变化,如果我们容量定为3,那么往里加的的数据最多就是3个,超过则会报错。

向管道写入数据:管道名<- 需要写入的变量(或值)示例:

var intChan chan int         //定义int类型的管道
var num int = 15
intChan = make (chan int, 3) //初始化
intChan<- 3                  //写入数据
intChan<- num                //写入数据

向管道中读取数据:变量名 = <-管道名。注:如果管道数据都取完了,还在继续取,编译就会报错。延续上面代码进行演示(因为管道是先进先出,所以下面代码的num2应该是3):

var num2 int
num2 = <-intChan

假如我想要第二个数据,第一个数据我又不想定义个变量去存放,我们就可以直接输入<-intChan实现,即把数据推出。

channel的关闭和遍历

channel的关闭

我们可以使用内置的close语句实现管道的关闭。关闭后的管道就不能再往里面继续写入数据,但仍然可以读取数据。语法是:close(管道变量名)

channel的遍历

下面我们将使用for range语句对管道遍历。但前提是管道必须已经关闭,如果没有关闭则会报错。因为它不知道什么时候结束,会一直遍历,就会报deadlock的错误。

close(intChan)
for v:= range intChan{
    fmt.Println("v=",v)
}

重点:管道遍历的返回值只有value,因为管道是先进先出,所以它没有下标。