channel(管道)底层是一个环形队列(先进先出),send(插入)和recv(取走)从同一个位置沿同一个方向顺序执行。sendx表示最后一次插入元素的位置,recvx表示最后一次取走元素的位置。
var ch chan int //管道的声明
ch = make(chan int, 8) //管道的初始化,环形队列里可容纳8个int
ch <- 1 //往管道里写入(send)数据
ch <- 2
ch <- 3
ch <- 4
ch <- 5
v := <-ch //从管道里取走(recv)数据
fmt.Println(v)
v = <-ch
fmt.Println(v)
read_only := make (<-chan int) //定义只读的channel
write_only := make (chan<- int) //定义只写的channel
定义只读和只写的channel意义不大,一般用于在参数传递中。
//只能向channel里写数据
func send(c chan<- int) {
c <- 1
}
//只能取channel中的数据
func recv(c <-chan int) {
_ = <-c
}
//返回一个只读channel
func (c *Context) Done() <-chan struct{} {
return nil
}
可以通过for range的方式遍历管道,遍历前必须先关闭管道,禁止再写入元素。
close(ch) //遍历前必须先关闭管道,禁止再写入元素
//遍历管道里剩下的元素
for ele := range ch {
fmt.Println(ele)
}
slice、map和channel是go语言里的3种引用类型,都可以通过make函数来进行初始化(申请内存分配)。因为它们都包含一个指向底层数据结构的指针,所以称之为“引用”类型。引用类型未初始化时都是nil,可以对它们执行len()函数,返回0。