channel

主要用于多个goroutine间传递数据.一个通道相当于一个先进先出(FIFO)的队列

  • 非缓冲通道
    make的时候第二个参数为0或者不填.
    无论是发送操作还是接收操作,一开始执行就会被阻塞,直到配对的操作也开始执行才会继续传递。由此可见,非缓冲通道是在用同步的方式传递数据。也就是说,只有收发双方对接上了,数据才会被传递.数据是直接从发送方复制到接收方的,中间并不会用非缓冲通道做中转
  • 缓冲通道
    make 的时候第一个参数大于0.
    在有容量的时候,发送和接收是不会互相依赖的.用异步的方式传递数据。

特性

  • 是类型安全的
  • 发送操作之间是互斥的,接收操作之间也是互斥的
  • 进入通道的并不是在接收操作符右边的那个元素值,而是它的副本
  • 移出通道的通道的是通道元素的副本
  • channel关闭后,如果还有数据还是可以正常读取的
  • 通道会阻塞goroutine

阻塞的Case

  • 通道容量已满情况,执行写入
  • 通道没有数据,执行读取
  • 对于值为nil的通道,不论它的具体类型是什么,对它的发送操作和接收操作都会永久地处于阻塞状态。它们所属的 goroutine 中的任何代码,都不再会被执行.实际代码测试是不正确的

panic的case

  • 关闭已经关闭的channel
  • 已经关闭的channel发送数据

单向通道

 make(chan<- int, 1)
make(<-chan int, 1)

作用

途就是约束其他代码的行为

//1.函数返回一个单向通道,通过函数获取的通道就能接收,不能发送
func getIntChan() <-chan int {
 num := 5
 ch := make(chan int, num)
 for i := 0; i < num; i++ {
 ch <- i
 }
 close(ch)
 return ch
}

//2.定义interface.如果我们在某个方法的定义中使用了单向通道类型,那么就相当于在对它的所有实现做出约
束。
type Notifier interface {
 SendInt(ch chan<- int)
}

推荐阅读更多精彩内容