Есть два канала. Нужно вернуть третий, в который попадают значения из обоих.
В отличие от общего fan-in на N каналов, здесь просят обойтись одной
горутиной с select внутри.
func Merge(a, b <-chan int) <-chan int
Требования
- В выход попадает каждое значение из
a и b ровно один раз. Порядок между
каналами любой, внутри одного канала сохраняется.
- Пустой открытый канал не мешает получать значения из другого.
- Выход закрывается, когда закрыты и вычитаны оба входа (в том числе если
оба закрыты с самого начала).
- Вся работа — в одной горутине: никаких горутин на каждый вход и
отдельной горутины для
close.
- После закрытия выхода горутин не остаётся. Код проходит
go test -race.
Пример
a, b := make(chan int), make(chan int)
go func() { defer close(a); a <- 1; a <- 2 }()
go func() { defer close(b); b <- 10 }()
for v := range Merge(a, b) {
fmt.Println(v) // 1, 2, 10 в каком-то порядке (1 раньше 2)
}
func MergePriority(high, low <-chan int) <-chan int
- То же, что
Merge, но если значения готовы в обоих каналах, первым
уходит значение из high.
- Пока
high пуст (но открыт), значения из low идут без задержки.
Устно: как select выбирает ветку, если готовы несколько? Что делает
ветка default и чем блокирующая операция с каналом отличается от
неблокирующей? Что происходит при чтении из nil-канала и из закрытого?
Разбор и эталонное решение — после своей попытки: на собеседовании подсказок не будет.
Сначала попробуй сам — подсказки не дают готовый ответ.