据我所知,在函数中处理生产者通道有两种方法:(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
}
}()
}
Run Code Online (Sandbox Code Playgroud)
恕我直言:这取决于。
producer1对于该通道的行为和生命周期非常明确(这可能是一件好事),
producer2允许您将这些值的发射插入到一些更大的上下文中(这也可能是一件好事)。
“好东西”的概念实际上取决于您打算如何在这些功能之外使用这些渠道。
一项额外说明:producer2不处理通道的创建,我还将从此函数中删除关闭通道的行。
如果您想知道 Producer2 是否已完成其任务,您可以使用其他方式来发出信号,例如:
func producer2(numbers []int, out <-chan int) (done <-chan struct{}) {
done = make(chan struct{})
go func() {
defer close(done)
for _, n := range numbers {
out <- n
}
}()
return done
}
// a caller may check '<-done' to see if producer2 has finished feeding all
// of its numbers into the 'out' channel
Run Code Online (Sandbox Code Playgroud)
使用ch := producer1([]int{1, 2, 3, 4})简化了这两行:
out := make(chan int)
producer2([]int{10, 20, 30, 40}, out)
Run Code Online (Sandbox Code Playgroud)
成一行:
ch := producer1([]int{1, 2, 3, 4})
Run Code Online (Sandbox Code Playgroud)
因此,当您多次需要时,第一个用例是代码简化(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
}
}()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2477 次 |
| 最近记录: |