Для каждого входа запустите пересылку, а выход закройте после завершения всех пересыльщиков. WaitGroup предотвращает преждевременный close.
Объединение нескольких каналов в один
Для каждого входа запустите пересылку, а выход закройте после завершения всех пересыльщиков. WaitGroup предотвращает преждевременный close.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо реализовать функцию merge, которая принимает произвольное количество входных каналов только для чтения (<-chan int) и возвращает единый выходной канал того же типа. Функция должна гарантировать, что все значения, поступающие во все входные каналы, будут переданы в результирующий канал.
func merge(channels ...<-chan int) <-chan int {
// ...
}
Ответ
Для каждого входа запустите пересылку, а выход закройте после завершения всех пересыльщиков. WaitGroup предотвращает преждевременный close.
Nil-каналы здесь считаются отсутствующими источниками:
import "sync"
func merge(channels ...<-chan int) <-chan int {
out := make(chan int)
var wg sync.WaitGroup
for _, ch := range channels {
if ch == nil { continue }
wg.Add(1)
go func(ch <-chan int) {
defer wg.Done()
for value := range ch { out <- value }
}(ch)
}
go func() {
wg.Wait()
close(out)
}()
return out
}
Порядок отдельного источника сохраняется, общий порядок не задан. Входы должны закрываться, потребитель — дочитывать выход. Для раннего ухода потребителя нужно расширить контракт context и учитывать отмену при чтениях и отправках.