Объединение нескольких каналов в один

Для каждого входа запустите пересылку, а выход закройте после завершения всех пересыльщиков. 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 и учитывать отмену при чтениях и отправках.

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

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

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

Подробнее