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