Идея состоит в том, чтобы иметь переменное количество каналов в срезе, нажимать каждое полученное через них значение в один канал и закрывать этот выходной канал после закрытия последнего из входных каналов. Нечто подобное, но для ряда каналов более два:Можно ли мультиплексировать несколько каналов в один?
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
случая, который хорошо (EDIT: это похоже на присутствие «хорошо» делает оператор select неблокирующим, и цикл занят в конце концов. Но для примера подумайте о коде, как будто он будет блокироваться). Может ли такая же функциональность быть достигнута и с произвольным количеством входных каналов? Очевидно, что это можно было бы сделать, уменьшив разрез попарно до одного канала, но я был бы более заинтересован в более простом решении, если это возможно.
Ах, очень хорошее решение, понятно и лаконично. Спасибо! – elpres
Теперь есть пакет с функцией (https://godoc.org/github.com/eapache/channels#Multiplex), который решает проблему, используя отражение вместо нескольких goroutines. – Evan