Каналы производителей Голанга в качестве параметра или в качестве возвращаемого значения

Насколько я знаю, есть два способа обработки каналов производителей внутри функций: (1) как параметр или (2) как возвращаемое значение. В то время как для (1) функция является владельцем канала, владелец в (2) неизвестен (для функции.

Что более идиоматично, producer1 или же producer2? Я наблюдал за недостатком? Существуют ли конкретные сценарии использования?

Вот реализация (1) и (2):

func producer1(numbers []int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for _, n := range numbers {
            out <- n
        }
    }()
    return out
}

func producer2(numbers []int, out <-chan int) {
    go func() {
        defer close(out)
        for _, n := range numbers {
            out <- n
        }
    }()
}

2 ответа

ИМХО: это зависит.

producer1 очень четко описывает поведение и время жизни этого канала (что может быть хорошо),
producer2 позволяет вам включить выброс этих значений в более широкий контекст (что также может быть хорошей вещью).

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


Еще одно замечание: producer2 не обрабатывает создание канала, я бы также удалил строку, которая закрывает канал из этой функции.

С помощью ch := producer1([]int{1, 2, 3, 4}) упрощает эти две строки:

out := make(chan int)
producer2([]int{10, 20, 30, 40}, out)

в одну строку:

ch := producer1([]int{1, 2, 3, 4})

Итак, первый вариант использования - это упрощение кода ( DRY), когда вам это нужно много раз.

Что более идиоматично, producer1 или же producer2?

для вашего примера использования producer1

Я наблюдал за недостатком?

да

Существуют ли конкретные сценарии использования?

DRY


Примечание: в producer2 Вы должны использовать только канал TX, как это out chan<- int вместо out <-chan int (только канал rx). как этот рабочий код (запустите буферизованный и небуферизованный):

package main

import "fmt"

func producer1(numbers []int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for _, n := range numbers {
            out <- n
        }
    }()
    return out
}

func main() {
    ch := producer1([]int{1, 2, 3, 4})
    for v := range ch {
        fmt.Println(v)
    }
    out := make(chan int)
    producer2([]int{10, 20, 30, 40}, out)
    for v := range out {
        fmt.Println(v)
    }
}

func producer2(numbers []int, out chan<- int) {
    go func() {
        defer close(out)
        for _, n := range numbers {
            out <- n
        }
    }()
}
Другие вопросы по тегам