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