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