Как исправить ошибку "panic: close of closed channel"?

Мне на курсах дали задачу:

"Напишите программу для подсчета суммы чисел в слайсе параллельно, используя горутины. Программа должна разделять исходный слайс на несколько слайсов и затем находить сумму каждой части в отдельной горутине. После этого подсчитывается финальная сумма. Программа должна реализовать следующий интерфейс:

type Summer interface{
// функция для нахождения суммы чисел
func ProcessSum(
// функция, которая будет вызываться для нахождения суммы части слайса.
// результат суммы записать в result
summer func(arr []int, result chan<- int),
// слайс с числами, сумму которых нужно найти
nums []int,
// сколько элементов в одной части (последняя часть может быть меньше)
сhunkSize int,
) (int, error) // вернуть сумму чисел
}

Также нужно реализовать функцию SumChunk(arr []int, result chan<- int), которая будет вызываться для нахождения суммы части слайса (summer). В случае возникновения ошибок верните 0 и возникшую ошибку."

Вот мой код:

package main

import (
    "fmt"
)

type Summer interface {
    ProcessSum(summer func(arr []int, result chan<- int), nums []int, chunkSize int) (int, error)
}

func SumChunk(arr []int, result chan<- int) {
    go func() {
        defer close(result)
        var sum int
        for i := range arr {
            sum += arr[i]
        }
        result <- sum
    }()
}

func ProcessSum(summer func(arr []int, result chan<- int), nums []int, chunkSize int) (int, error) {
    if chunkSize <= 0 {
        return 0, fmt.Errorf("invalid chunkSize")
    }

    var sum int
    out := make(chan int)

    for i := 0; i < len(nums); i += chunkSize {
        end := i + chunkSize
        if end > len(nums) {
            end = len(nums)
        }
        go summer(nums[i:end], out)
        
        sum += <-out
    }
    close(out)
    return sum, nil
}

Как мне исправить ошибку "panic: close of closed channel"? Помогите пожалуйста :(


Ответы (1 шт):

Автор решения: Kirill Veresnikov

В функции SumChunk есть defer в котором выполняется закрытие канала, тоже самое выполняется в вызывающей функции. Вероятно, стоит оставить закрытие канала на откуп вызывающей функции т.е ProcessChunk

→ Ссылка