想法是在片中具有可变数量的通道,将通过通道接收的每个值推入单个通道,并在最后一个输入通道关闭后关闭该输出通道。这样的事情,但对于多个渠道来说,要超过两个:
func multiplex(cin1, cin2, cout chan int) { n := 2 for { select { case v, ok := <-cin1: if ok { cout <- v } else { n -= 1 } case v, ok := <-cin2: if ok { cout <- v } else { n -= 1 } } if n == 0 { close(cout) break } } }
上面的代码避免了繁忙的循环,因为没有任何default情况,这是很好的(编辑:看起来,“,ok”的存在使select语句成为非阻塞状态,并且循环毕竟是繁忙的。但是出于示例的目的,就好像将代码阻止一样)。是否可以通过任意数量的输入通道来实现相同的功能?显然,这可以通过将片段对成对减少到单个通道来完成,但如果可能的话,我将对更简单的解决方案更感兴趣。
default
我相信这段代码可以满足您的需求。我已经更改了签名,以便清楚地知道输入和输出仅应用于一个方向的通信。请注意,添加了一个sync.WaitGroup,您需要某种方式让所有输入信号表示它们已完成,这很容易。
sync.WaitGroup
func combine(inputs []<-chan int, output chan<- int) { var group sync.WaitGroup for i := range inputs { group.Add(1) go func(input <-chan int) { for val := range input { output <- val } group.Done() } (inputs[i]) } go func() { group.Wait() close(output) } () }