Этот пример порождает меньшее количество горутин, а также гарантирует правильный порядок, независимо от того, какая горутина завершила свою обработку первой.
package main
import (
"fmt"
"sync"
)
type rowRes struct {
index int
result *[]int
}
func addRow(index int, row []int, numbers []int) rowRes {
result := make([]int, len(row))
for i, e := range row {
result[i] = e + numbers[i]
}
return rowRes{
index: index,
result: &result,
}
}
func main() {
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
matrix := [][]int{
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
}
rmatrix := make([][]int, 10)
// Buffered channel
rowChan := make(chan rowRes, 10)
wg := sync.WaitGroup{}
// Reciever goroutine
go recv(rowChan, rmatrix)
for i := range matrix {
wg.Add(1)
go func(index int, row []int, w *sync.WaitGroup) {
rowChan <- addRow(index, row, numbers)
w.Done()
}(i, matrix[i], &wg)
}
wg.Wait()
close(rowChan)
fmt.Println(rmatrix)
}
func recv(res chan rowRes, rmatrix [][]int) {
for {
select {
case k, ok := <-res:
if !ok {
return
}
rmatrix[k.index] = *k.result
}
}
}