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