channel
概念说明
channel 是 goroutine 之间传递数据的管道。
它既能传值,也能同步执行时机。
默认创建的是无缓冲 channel。
无缓冲 channel 的特点是:发送和接收必须同时准备好,否则其中一方就会等待。
语法/规则
- 使用
make(chan T)创建 channel。 - 使用
ch <- value向 channel 发送数据。 - 使用
value := <-ch从 channel 接收数据。 - 发送方可以使用
close(ch)关闭 channel,表示后面不会再发送数据。 - 使用
for value := range ch可以持续读取,直到 channel 被关闭。 - 不要向已经关闭的 channel 发送数据,会触发 panic。
语法模板
| |
channel 传递数据示例
| |
输出结果:
| |
怎么理解这个示例
- 一个 goroutine 发送数据,主 goroutine 负责接收并打印。
for number := range numbers会一直读,直到numbers被关闭。- 所以这个例子既展示了“怎么传值”,也展示了“怎么通知接收方数据发完了”。
什么时候会用到 channel
当多个 goroutine 之间需要传数据或配合同步时,就会用到 channel。
下面两个示例分别演示了“连续发送一组数据”和“把计算结果交回主 goroutine”这两种常见用法。
场景:后台计算结果后,把结果交给主 goroutine
goroutine 不能像普通函数那样直接把返回值交回调用位置。
这时可以让后台 goroutine 通过 channel 把结果送回来:
| |
输出结果:
| |
这个场景说明了什么
go sum(10, 20, resultCh)在后台计算结果。result := <-resultCh会等待结果到来,而不是靠time.Sleep猜时间。- 这就是 channel 的常见用法:一个 goroutine 算,一个 goroutine 收。
常见错误
- 只有发送没有接收,或只有接收没有发送,导致程序死锁。
- 接收方关闭 channel,容易让发送方继续发送时 panic;通常由发送方关闭。
- 误以为关闭 channel 是必须的,实际只有接收方需要判断结束时才需要关闭。
- 向已经关闭的 channel 发送数据,会触发
send on closed channel。