当所有通道都关闭时突破 Select 语句
考虑一个场景,多个 goroutine 向各个通道发送数据,并且您希望以任意顺序使用这些数据。使用 select 语句提供了一种处理来自多个源的并发输入的便捷方法。然而,当您仅在所有通道都关闭时才需要退出循环时,就会出现挑战。
朴素解决方案
直观的方法可能涉及检查每个通道的可用性通过使用 ok 标志。但是,此解决方案很容易出错,因为关闭的通道在被选择后会再次变得可用。这会导致无限循环,如这个游乐场示例所示:http://play.golang.org/p/rOjdvnji49。
改进的解决方案
更多有效的方法是利用零通道从未准备好进行通信的事实。每次通道关闭时,都可以将其设置为 nil,以确保将其从未来的 select 语句中排除。这保证了循环仅在所有通道关闭时终止:
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 } }
Playground 示例:http://play.golang.org/p/8lkV_Hffyj
实际注意事项
实际上,您不太可能需要处理大量通道单个选择语句。如果出现这种情况,建议使用更专业的解决方案,例如通道多路复用器,以避免过多的 nil 检查使代码变得混乱。
以上是Go中所有Channel都关闭时如何跳出Select语句?的详细内容。更多信息请关注PHP中文网其他相关文章!