当所有通道都关闭时跳出 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中文网其他相关文章!