Слияние нескольких каналов в единый поток

Для 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.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее