最近看到一段代碼邏輯很奇怪:返回一個已關閉的 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)
}
}
輸出:

