Go语言中的channel | 青训营笔记

80 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天,记录一下 Go 语言中 channel 的使用方法。

作用

Channel 是 goroutine 之间的一种通信机制,每个 channel 都有一个特定的类型,只能接收或发送该类型的数据。

创建

同 map 和 slice 一样,channel 需要通过 make 关键字来创建。下面的代码创建了一个无缓冲区的、可以接收和发送 int 类型数据的 channel。

 // make(chan 元素类型, [缓冲区大小])
 ch := make(chan int)
分类

根据有无缓冲区,可以分为无缓冲区 channel 和有缓冲区 channel。

在创建有缓冲区 channel 时,需要额外指定一个参数表示“缓冲区大小”。

 ch1 := make(chan string)        // 无缓冲区
 ch2 := make(chan string, 3)     // 有缓冲区,缓冲区大小为3

根据数据传输方向,可以分为只能接收数据的 channel、只能发送数据的 channel 和双向 channel。

 chan int        // 可以接受和发送 int 类型数据
 chan<- string   // 只能(向 channel)发送 string 类型数据
 <-chan float64  // 只能(从 channel)接收 float64 类型数据
数据传输

发送和接收数据的写法如下。

 ch := make(chan int, 1)
 ch <- 123       // 向 channel 中发送数据
 i := <- ch      // 从 channel 中接收数据
发送

对于无缓冲 channel 来说,当向其中发送数据时,如果此时没有接收者,则会一直阻塞,直到接收者到来,因此无缓冲 channel 也被称作“同步 channel”。

对于有缓冲 channel 来说,当向其中发送数据时,会先写入缓冲区,如果缓冲区满了则会一直阻塞,直到缓冲区有空位,因此有缓冲 channel 也被称作”异步 channel“。缓冲区可以看作是一个先入先出(FIFO)队列。

特别的,向一个被关闭的 channel 中发送数据会导致 panic,向 nil channel 中发送数据会一直阻塞。

接收

从 channel 中接收数据会一直阻塞,直到有数据可以接收。

特别的,从一个被关闭的 channel 中接收数据不会阻塞,而是立即返回,接收完已发送的数据后会返回对应类型的零值。