Каналы производителей Голанга в качестве параметра или в качестве возвращаемого значения - PullRequest
0 голосов
/ 16 декабря 2018

Насколько я знаю, есть два способа обработки каналов производителей внутри функций: (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 ]

0 голосов
/ 17 декабря 2018

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

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

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


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

0 голосов
/ 16 декабря 2018

Использование 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})

Поэтому первый вариант использования - это код упрощение ( СУХОЙ ), когда вам это нужно много раз.

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

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

Наблюдал ли я за недостатком?

Да

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

DRY


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

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
        }
    }()
}
...