Каналы производителей Голанга в качестве параметра или в качестве возвращаемого значения
Насколько я знаю, есть два способа обработки каналов производителей внутри функций: (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
Я наблюдал за недостатком?
да
Существуют ли конкретные сценарии использования?
Примечание: в 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
}
}()
}