我有以下代碼:package mainimport ( "fmt" "time")func main() { ch := make(chan int) ch2 := make(chan int) go func(c chan int, c2 chan int) { for { select { case v := <-c: fmt.Println(v) case v := <-c2: fmt.Println(v) default: } } }(ch, ch2) ch <- 1 close(ch) close(ch2) time.Sleep(10 * time.Second)}當我運行它時,它會打印1到標準輸出,然后繼續打印0。為什么是這樣?我知道我可以檢查我的 goroutine 中的通道是否關閉,但我只想知道原因。另外,假設我想在所有(多個)通道關閉后退出 goroutine,這可能嗎?我假設一旦所有通道都關閉,我可能會在默認情況下在所有通道關閉后退出 goroutine
2 回答

幕布斯7119047
TA貢獻1794條經驗 獲得超8個贊
這是每個規范的預期行為:接收運算符:
關閉通道上的接收操作始終可以立即進行,在收到任何先前發送的值后生成元素類型的零值。
如果您想在從通道接收到所有值(在關閉之前在通道上發送的值)后終止循環,請使用該for ... range
構造,例如:
c?:=?make(chan?int)?//?Initialize?some?channel for?v?:=?range?c?{ ????fmt.Println("Received:",?v) }
如果您有多個通道并且希望從所有通道接收數據,則可以使用多個 goroutine,每個 goroutine 都有一個for range
指定的通道。
另一個解決方案是:
函數可以從多個輸入中讀取數據,并通過將輸入通道復用到單個通道上來繼續執行,直到所有輸入都關閉,該通道在所有輸入都關閉時關閉。這稱為扇入。

catspeake
TA貢獻1111條經驗 獲得超0個贊
Go 編程語言規范
關閉
調用 close 后,并且接收到任何先前發送的值后,接收操作將返回通道類型的零值,而不會阻塞。
接收操作員
關閉通道上的接收操作始終可以立即進行,在收到任何先前發送的值后生成元素類型的零值。
- 2 回答
- 0 關注
- 164 瀏覽
添加回答
舉報
0/150
提交
取消