Golang生产者通道作为参数或返回值

时间:2018-12-16 10:22:01

标签: go channel

据我所知,有两种方法可以处理函数中的生产者通道:(1)作为参数或(2)作为返回值。对于(1)函数是通道的所有者,而(2)中的所有者是未知的(对于该函数。

producer1producer2是更惯用的语言吗?我监督过不利吗?有没有特定的使用场景?

以下是(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 :(得分:1)

使用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)。

  

producer1producer2是更惯用的语言吗?

对于您的示例用例producer1

  

我监督过劣势了吗?

  

有没有特定的使用场景?

DRY


注意:在producer2中,您必须使用像out chan<- int这样的仅tx通道,而不是out <-chan int(仅rx通道)。 像这样的工作代码(运行bufferednon-buffered):

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

答案 1 :(得分:1)

恕我直言:这取决于。

producer1非常清楚此频道的行为和生存期(这可能是一件好事),
producer2允许您在更大的上下文中插入这些值的发射(这也是一件好事)。

“好事”的概念实际上取决于您打算如何在这些功能之外使用这些渠道。


一个额外的说明:producer2不处理通道的创建,我还要从此函数中删除关闭通道的行。