Sobes.tech
Senior

Zadanie na Merge channel Zaimplementuj funkcję merge, która przyjmuje dowolną liczbę kanałów chan int i zwraca jeden kanał wyjściowy, z którego można odczytać wszystkie wartości z przekazanych kanałów. Przekazane kanały poza funkcją merge są zamykane po zapisaniu. Po zakończeniu odczytu z połączonego kanału program powinien wyświetlić "ok".

sobes.tech AI

Odpowiedź od AI

Ниже пример реализации функции merge, которая принимает произвольное количество каналов chan int и возвращает один канал, из которого можно читать все значения. После закрытия всех входных каналов выходной канал тоже закрывается, и программа выводит "ok".

package main

import (
	"fmt"
	"sync"
)

func merge(channels ...chan int) chan int {
	out := make(chan int)
	var wg sync.WaitGroup

	wg.Add(len(channels))

	for _, ch := range channels {
		go func(c chan int) {
			defer wg.Done()
			for v := range c {
				out <- v
			}
		}(ch)
	}

	go func() {
		wg.Wait()
		close(out)
	}()

	return out
}

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)

	go func() {
		defer close(ch1)
		ch1 <- 1
		ch1 <- 2
	}()

	go func() {
		defer close(ch2)
		ch2 <- 3
		ch2 <- 4
	}()

	merged := merge(ch1, ch2)

	for v := range merged {
		fmt.Println(v)
	}

	fmt.Println("ok")
}

В этом примере:

  • Для каждого входного канала запускается горутина, которая читает из него и отправляет значения в общий канал out.
  • Используется sync.WaitGroup для ожидания завершения чтения из всех каналов.
  • После того, как все входные каналы закрыты и данные прочитаны, выходной канал закрывается.
  • В main после чтения всех значений выводится "ok".