把 Channel 想成“goroutine 之间传东西的管道”。chan int 表示“这根管道里只能传 int”。
make(chan int)
没有存货位置,容量是 0。
ch := make(chan int) fmt.Println(cap(ch)) // 0
make(chan int, 3)
内部最多暂存 3 个 int。
ch := make(chan int, 3) fmt.Println(cap(ch)) // 3
三个必须认识的符号
| 语法 | 含义 | 读法 |
|---|---|---|
ch <- 10 | 向 Channel 发送 10 | 把 10 放进 ch |
x := <-ch | 从 Channel 接收一个值 | 从 ch 拿一个值给 x |
x, ok := <-ch | 接收值,同时判断是否还收到真正发送过的数据 | ok 为 false 表示 channel 已关闭且已经没有数据 |
<- 的箭头方向就是数据流方向。
ch <- v:数据流进 ch;v := <-ch:数据从 ch 流出来。
为什么通常要配 goroutine?
ch := make(chan int) ch <- 10 // 这里会一直等接收者 x := <-ch // 永远走不到这里
无缓冲 Channel 的发送需要有人同时接收。这里只有一个 goroutine,它自己卡在发送处,后面的接收语句永远执行不到,因此运行时最终会报死锁。
ch := make(chan int) go func() { ch <- 10 }() x := <-ch fmt.Println(x)
go func() { ... }() 表示启动一个新的 goroutine。现在“发送”和“接收”可以由两个 goroutine 配对。