“<-chan" 和 "chan" 作为函数返回类型的区别是什么?

huangapple go评论61阅读模式
英文:

What's the difference between "<-chan" and "chan" as a function return type?

问题

Golang新手在这里。

这两种写法有什么功能上的区别吗?

func randomNumberGenerator() &lt;-chan int {

func randomNumberGenerator() chan int {

我尝试使用这两种写法,它们对我来说都能正常工作。

我在Rob Pike(Go语言的创造者之一)在2012年的Google IO大会上的Go并发模式演讲中看到过前一种写法。我也在Go官方网站上看到过这种写法。为什么要多加两个字符("<-")呢?我尝试在网上找到区别,但没有找到。

英文:

Golang newbie here.

Is there a functional difference between

func randomNumberGenerator() &lt;-chan int {

and

func randomNumberGenerator() chan int {

I've tried using both and they seem to work fine for me.

I've seen the former used by Rob Pike (one of Go creators) in his Go Concurrency Patterns talk at Google IO 2012. I've also seen it used in Go's official website. Why add 2 extra characters ("<-") when you can omit it? I've tried looking for the difference on the web, but couldn't find it.

答案1

得分: 115

两种形式都可以使用。但是其中一种更加限制性。箭头指向chan关键字的形式意味着返回的通道只能被客户端代码拉取,不允许推送:推送操作将由随机数生成器函数完成。相反,还有一种箭头指向chan的形式,使得该通道对客户端只能进行写操作。

chan   // 读写
<-chan // 只读
chan<- // 只写

这些额外的限制可以提高意图表达和加强类型系统:试图将内容强制写入只读通道将导致编译错误,同样,试图从只写通道读取数据也会导致编译错误。这些限制可以在返回类型中表达,也可以作为参数签名的一部分。例如:

func log(<-chan string) { ...

通过函数签名,你可以知道log函数将从通道中消费数据,而不会向其发送任何数据。

英文:

Both will work indeed. But one will be more constraining. The form with the arrow pointing away from the chan keyword means that the returned channel will only be able to be pulled from by client code. No pushing allowed : the pushing will be done by the random number generator function. Conversely, there's a third form with the arrow pointing towards chan, that makes said channel write-only to clients.

chan   // read-write
&lt;-chan // read only
chan&lt;- // write only

These added constraints can improve the expression of intent and tighten the type system : attempts to force stuff into a read-only channel will leave you with a compilation error, and so will attempts to read from a write-only channel. These constraints can be expressed in the return type, but they can also be part of the parameter signature. Like in :

func log(&lt;-chan string) { ...

There you can know, just by the signature, that the log function will consume data from the channel, and not send any to it.

答案2

得分: 16

这是一个只接收通道的示例。

可选的<-操作符指定通道的方向,发送或接收。如果没有给出方向,则通道是双向的。通过转换或赋值,可以将通道限制为仅发送或仅接收。告诉API的用户他们应该从该通道接收,永远不要发送,否则会发生糟糕的事情。在公共API中指定通道的方向被认为是一种良好的实践。另请参阅:使用通道设计Go API的原则

英文:

This is an example of a receive-only channel.

>The optional &lt;- operator specifies the channel direction, send or receive. If no direction is given, the channel is bidirectional. A channel may be constrained only to send or only to receive by conversion or assignment.

It's useful to tell the users of your API that they should only receive from that channel and never send, otherwise bad things happen. It is considered a good practice to specify the direction of your channels in public APIs. See also: Principles of designing Go APIs with channels.

huangapple
  • 本文由 发表于 2015年8月10日 21:04:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/31920353.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定