在go(golang)函数中将通道作为参数传递的不同方法

时间:2014-07-21 15:26:14

标签: concurrency go channel

我正在阅读一些go代码并说几种不同的方式来传递频道。也许他们是一样的,但我想知道是否有任何差异因为我在网上找不到文件:

1)

func serve(ch <-chan interface{}){ //do stuff }

2)

func serve(ch chan<- interface{}){ //do stuff }

3)

func serve(ch chan interface{}){ //do stuff }

4)

func server(ch *chan interface{}){ //do stuff}

我想知道它们之间有什么区别,如果它们只是等同的方式来做同样的事情:在不同的goroutines周围传递一个通道。

注意:我知道没有理由将指针传递给chan,map或slice或函数值,因为这些都是内部包含指针的引用类型(例外情况是如果你想要的话被调用者更改引用类型标题)。我提供它的唯一原因是为了完整性(即真正提供通道可以尝试作为参数传递的每一种方式,并提出有希望的问题,引用所有方法来做这个并比较它们。)

3 个答案:

答案 0 :(得分:50)

我总是建议在任何可能的地方传递方向,例如

func serve(ch <-chan SomeType) { /*do stuff*/ }

func serve(ch chan<- SomeType) { /*do stuff*/ }

通过加入箭头<-chanchan<-,您将完成三件事:

  • 您明确表示该参数是频道的结束
  • 您清楚地表达正在提供结尾。
  • 您正在向编译器提供更多信息以供检查。如果函数体试图使用通道的错误结束,编译器可能会引发错误。

这些是在可能的情况下显示频道结尾的充分理由。

您的第三个案例描述 not 指定频道的结尾。这允许访问通道的两端,这在某些情况下是正确的,但在其他情况下可能会导致意外错误。

第四种情况,将指针传递给一个通道,这很不寻常,也许有点奇怪。如果您想更改频道,则将其作为返回参数包含在内会更加清晰。

答案 1 :(得分:21)

这些是不同的类型频道。见http://golang.org/ref/spec#Channel_types。对于指针的东西:不常见,但如果你想从函数内部改变通道可能会很有用(从来没有在野外看到过)。

答案 2 :(得分:18)

经验法则:箭头显示数据是进入(输出)还是离开(输入)通道。没有箭头是通用渠道。

chan <-          writing to channel (output channel)
<- chan          reading from channel (input channel)
chan             read from or write to channel (input/output channel)