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

Для разных конкретных типов каналов можно применять reflect.Select и возвращать chan any. Обобщённая merge[T] проще, но требует одинакового T у всех входов одного вызова.

Короткий ответ

Что ответить на собеседовании

Для разных конкретных типов каналов можно применять reflect.Select и возвращать chan any. Обобщённая merge[T] проще, но требует одинакового T у всех входов одного вызова.

Подробный разбор

Ответ с пояснениями

Условие

Реализуйте функцию, которая принимает несколько каналов и собирает все поступающие из них значения, формируя один общий результат. Функция должна корректно работать с каналами разного типа и обеспечивать завершение после обработки всех входных потоков.

Ответ

Для разных конкретных типов каналов можно применять reflect.Select и возвращать chan any. Обобщённая merge[T] проще, но требует одинакового T у всех входов одного вызова.

Реализация с импортом reflect:

func merge(channels ...any) <-chan any {
    cases := make([]reflect.SelectCase, 0, len(channels))
    for _, ch := range channels {
        value := reflect.ValueOf(ch)
        if !value.IsValid() { continue }
        if value.Kind() != reflect.Chan || value.Type().ChanDir() == reflect.SendDir {
            panic("expected receive-capable channel")
        }
        if value.IsNil() { continue }
        cases = append(cases, reflect.SelectCase{Dir: reflect.SelectRecv, Chan: value})
    }
    out := make(chan any)
    go func() {
        defer close(out)
        for len(cases) > 0 {
            chosen, value, ok := reflect.Select(cases)
            if !ok {
                cases[chosen] = cases[len(cases)-1]
                cases = cases[:len(cases)-1]
                continue
            }
            out <- value.Interface()
        }
    }()
    return out
}

Nil-каналы пропускаются, закрытые удаляются из набора. Порядок произволен. Для раннего ухода получателя нужен context; без него результат читают до конца. Reflection дороже типизированного fan-in, число case имеет ограничения runtime.

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

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

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

Подробнее