最近看到一段代码逻辑很奇怪:返回一个已关闭的 channel 给其他 goroutine 读取使用。这让我产生了一个疑问,很多文章说“从已关闭的 chan 读数据永远不会阻塞,一律返回空值”,为什么还会对channel进行关闭后返回?
代码如下:
func gen(nums ...int) <-chan int { out := make(chan int) go func() { for _, n := range nums { out <- n } close(out) }() return out }
实际测试后发现,“从已关闭的 chan 读数据永远不会阻塞,一律返回空值”这句话并不正确。下面的测试代码在关闭 channel 之后继续对 channel 读取,还是可以读取到缓冲区的结果。
结论是:从已关闭的 channel 接收数据,返回已缓冲数据或零值。
测试代码如下:
package main import ( "time" ) var ch chan int func f() { ch = make(chan int, 5) println("start") for i := 1; i < 5; i++ { ch <- i } close(ch) println("close") } func main() { go f() time.Sleep(time.Second * 1) println("closed") for c := range ch { println(c) } }
输出: