1. 声明和类型

ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .

声明
双向:var ReadAndWriteChannel chan int
仅可读:var OnlyReadChannel <- chan int
仅可写:var OnlyWriteChannel chan <- int
初始化:
make(chan int)  //坑:没有数据,读取阻塞,直至写入数据
make(chan int,100) // 容量 缓存 buffer

2. 操作

c := make(chan int)
读:i := <- c
写: c <- (7+2)
遍历: range c
关闭: close(c) 坑:关闭channel,可读,不可写(panic)

多值接收:判断是否关闭
x,ok := <-c //(ok == false 关闭)

阻塞情况一览

这些阻塞可能引起 deadlock——阻塞致死

  1. 无缓冲 channel:

    1. 需要接收和发送同时准备好,任意一方未准备好都会阻塞;
    package main
    
     import (
         "fmt"
         "time"
     )
    
     func main() {
         c := make(chan int)
         //c <-1 不能放这里,recv没准备好
         //fatal error: all goroutines are asleep - deadlock!
         //
         //goroutine 1 [chan send]:
    
         go func() {
             m := <-c
             fmt.Println(m)
         }()
    
         c <-1
    
         time.Sleep(time.Second)
     }
    
  2. 有缓冲 channel:

    1. buffer 满了后 send 才会阻塞
    2. buffer 空了后 recv 会阻塞
  3. 关闭之后,send 阻塞

  4. select 没有条件

    fatal error: all goroutines are asleep - deadlock!
    
    goroutine 1 [select (no cases)]: