當所有通道都關閉時跳出Select 語句
在Go 中,使用select 語句是處理多個通道的有效方法同時地。然而,當處理最終關閉的通道時,有必要找到一種簡潔的方法來循環,直到所有通道都關閉。
讓我們考慮以下範例,其中兩個 goroutine 獨立產生資料並將其發送到通道。主 Goroutine 消耗這些數據而不考慮順序。
for { select { case p, ok := <-mins: if ok { fmt.Println("Min:", p) } case p, ok := <-maxs: if ok { fmt.Println("Max:", p) } } }
雖然此 select 語句允許在每個輸出到達時消耗它們,但當兩個通道都關閉時,無法明確地跳出循環。
建議的解決方案涉及使用布林標誌追蹤每個通道的狀態,對於大量通道來說可能會變得笨拙。
更優雅的解決方案是在以下情況下將 nil 分配給通道:它已經關閉了。這可以確保永遠不會選擇 nil 通道進行通訊。
for { select { case x, ok := <-ch: fmt.Println("ch1", x, ok) if !ok { ch = nil } case x, ok := <-ch2: fmt.Println("ch2", x, ok) if !ok { ch2 = nil } } if ch == nil && ch2 == nil { break } }
透過使用 nil 通道,select 語句將自動跳過已關閉的通道。當所有通道都關閉時,循環就會中斷。此解決方案提供了一種乾淨有效的方法來處理 select 語句中關閉通道,無論涉及的通道數量為何。
以上是Go 中所有 Channel 都關閉時如何跳出 select 語句?的詳細內容。更多資訊請關注PHP中文網其他相關文章!