创建一个int类型的channel
ch := make(chan int)
一个channel是一个通信机制。
当我们复制一个channel时,只是拷贝了一个channel的引用,用于函数调用时,调用者和被调用者将引用同一个channel。
两个同类型的channel可以使用==运算符比较。channel的零值为nil,故channel也可以与nil进行比较。
// 通道变量 <- 值
// 发送数据x到ch中
ch <- x
// 接收数据
// 1.阻塞模式接收数据时,将接收变量作为<-操作符的左值,格式如下
data := <-ch
// 2.使用非阻塞方式从通道接收数据时,语句不会发生阻塞,格式如下
data, ok := <-ch
// 3.阻塞接收数据后,忽略从通道返回的数据,格式如下
<-ch //执行该语句时将会发生阻塞,直到接收到数据,但接收到的数据会被忽略
// 4.通道的数据接收可以借用 for range 语句进行多个元素的接收操作,格式如下
for data := range ch {
...
}
// 关闭channel
close(ch)
不带缓冲的Channels
不带缓冲的Channels 即channel的容量为0,当其容量大于0时,该channel就是带缓冲的channel。
ch := make(chan int)
// or
ch := make(chan int, 0)
无缓冲的channel可被称作是同步channel,因为一个基于无缓冲channels的发送操作将导致发送者goroutine阻塞,直到另一个goroutine在相同的channels上执行接收操作,当发生的值通过channels成功传输之后,两个goroutine可以继续执行后面的语句。
串联的Channels(Pipeline)
channel可以用于将多个goroutine连接在一起,一个Channel的输出作为下一个Channel的输入-->管道 pipeline
可以使用range循环直接在channels上面迭代。其将会从channel接收数据,当channel被关闭并且没有值可以接收时跳出循环。
不管一个channel是否被关闭,当它没有被引用时将会被Go语言的GC回收。
单方向的Channels
当一个channel作为一个函数参数时,一般总是被专门用于只发送或者只接收。
// 只发送int的channel
chan <- int
// 只接收int的channel
<-chan int
上面这种限制在编译的时候就会检测。
关闭操作只用于断言不再向channel发送新的数据,所以在只发送时,goroutine才会调用close函数,只接收的channel调用close会是一个编译错误。
带缓冲的Channels
ch := make(chan int, 3)
向缓冲channel发送操作就是向内部缓冲队列的尾部插入元素,接收操作则是从队列的头部删除元素。
阻塞情况:
- 如果内部缓冲队列满,发送操作将阻塞直到另外一个goroutine执行接收操作释放新的队列空间;
- 如果channel为空,接收操作将阻塞直到另外一个goroutine执行发送操作向队列插入元素。
channel的内置函数:
// 获取容量
cap(ch)
// 获取有效元素个数
len(ch)