最近看到一段代码逻辑很奇怪:返回一个已关闭的 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)
}
}
输出:
