1

引用Go 编程语言规范

“选择”语句选择一组可能的通信中的哪一个将进行。它看起来类似于“switch”语句,但所有案例都涉及通信操作。

如何在一个子句中等待多个通道case,以便只有当两个通道都返回时才执行案例?

示例

select {

   case <-ch1, <-ch2 ... : //wait for ch1 and ch2 
        // do something 
   case  ..
}
4

1 回答 1

5

没有办法在同一个选择案例中等待多个通道,也没有办法在选择案例中“失败”,如文档所述:

不过,您可以通过其他方式轻松地做这样的事情。

没有选择:

这仅适用于尽管 c2 可用但保证 c1 返回的情况。

v1 := <-c1
v2 := <-c2

带循环:

尽管有排序,这仍然有效,但 c1 和 c2 只能触发一次,否则可能会出现异常:

var v1, v2 int
for i := 0; i < 2; i++ {
    select {
    case v1 = <-c1:
    case v2 = <-c2:
    }
}
// both v1 and v2 are set here

使用 goroutine:

无论哪种方式,这都有效,但是您会丢失结果的顺序:

c3 := make(chan int, 2)
go func() { c3 <- (<-c1) }()
go func() { c3 <- (<-c2) }()

first := <-c3
second := <-c3

使用 sync.WaitGroup:

这两种方式都有效:

var wg sync.WaitGroup
var v1, v2 int
wg.Add(2)
go func() {
    v1 = <-c1
    wg.Done()
}()
go func() {
    v2 = <-c2
    wg.Done()
}()
wg.Wait()
// v1 and v2 are both set

等等。当然还有其他方法。最好的取决于您要实现的目标的细节。

于 2013-09-07T17:32:18.290 回答