Через один канал, в который пишут все горутины; читать в цикле или через for range до закрытия. Либо использовать WaitGroup и общую структуру с мьютексом. Либо errgroup с общим слайсом результатов (с защитой мьютексом).
ch := make(chan int, N)
for i := 0; i < N; i++ { go func(i int) { ch <- work(i) }(i) }
for i := 0; i < N; i++ { results = append(results, <-ch) }