在 Go 语言中,如果对一个已经关闭的 channel 执行读操作或写操作,分别会产生什么结果?请说明其背后的原因。
考察说明
考查对 Go 语言 channel 关闭后读写行为的理解,以及底层原理。
回答思路
- 【回答框架 1】对已关闭 channel 执行读操作:如果 channel 中有缓冲数据,可以继续读出这些数据;当缓冲数据读完后,再读会立即返回该 channel 元素类型的零值,且第二个返回值(ok)为 false。
- 【回答框架 2】对已关闭 channel 执行写操作:会导致 panic,因为向已关闭的 channel 发送数据是非法操作,运行时检测到会触发 panic。
- 【回答框架 3】原因在于 channel 关闭后,其内部状态被标记为 closed,读写操作会检查该状态;读操作在无数据时返回零值和 false 以通知接收方通道已关闭,而写操作则直接触发 panic。
- 【回答框架 4】另外,重复关闭一个 channel 或关闭一个 nil channel 也会导致 panic。关闭 channel 后,select 语句中的该 channel 分支会持续可读,返回零值。
- 【回答框架 5】在实践中,通常由发送方负责关闭 channel,接收方不要关闭,避免向已关闭 channel 发送数据导致的 panic。
- 【关键点 1】已关闭 channel 读操作:缓冲耗尽后返回零值和 false。
- 【关键点 2】已关闭 channel 写操作:触发 panic。
- 【关键点 3】关闭 channel 由发送方负责,接收方不应关闭。
- 【易错点 1】不要向已关闭 channel 发送数据,否则 panic。
- 【易错点 2】不要重复关闭 channel,也会 panic。