为什么通道类型中有一个’<-'?

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

Why does the channel type have a '<-' in it?

问题

这个有效。

var tick &lt;-chan time.Time = time.Tick(1e8)

然而,这个无效。

var tick chan time.Time = time.Tick(1e8)

为什么在通道的类型声明中需要一个&lt;-?我以为&lt;-是用来向通道写入或从通道读取的。为什么它会出现在类型中?

英文:

This works.

var tick &lt;-chan time.Time = time.Tick(1e8)

However, this does not.

var tick chan time.Time = time.Tick(1e8)

Why do I need a &lt;- in my type declaration for a channel? I thought that &lt;- was for writing to or reading from a channel. Why would it appear in a type?

答案1

得分: 19

通道可以有一个类型,指示它是只读、只写还是两者兼有。

指示通道方向是通过<-作为类型的一部分来完成的,或者在读/写通道中省略。

因此,在&lt;-chan time.Time中的&lt;-是类型的一部分,

chan   time.Time  //将是一个可读/可写通道
chan&lt;- time.Time  //将是一个只写通道
&lt;-chan time.Time  //将是一个只读通道

time.Tick(1e8)返回一个只读通道。

在语言规范中阅读更多信息这里

英文:

Channels can have a type indicating whether it is readonly, writeonly or both.

Indicating a channel direction is done with <- as part of the type or omitted for a read/write channel.

So the &lt;- in &lt;-chan time.Time is part of the type,

chan   time.Time  //Would be a read/writable channel
chan&lt;- time.Time  // Would be a write only channel
&lt;-chan time.Time  // Would be a read only channel

and time.Tick(1e8) returns a read only channel.

Read more in the language spec here

答案2

得分: 4

一个好的思考通道的方式是将其视为两端的管道。一个端口是事件流入的地方,另一个端口是事件流出的地方。因此,声明一个通道,例如:

var c = make(chan int)

创建一个完整的通道 - 即具有两个端口。相反地,

func consume(c &lt;-chan int) {
    ...
}

定义了一个带有通道输入参数的函数 - 即通道的可读端口,而

func generate(c chan&lt;- int) {
    ...
}

定义了一个带有通道输出参数的函数 - 即通道的可写端口。这两个函数都可以将整个通道作为实际参数传递,也可以只传递它们需要的端口。

当通道用作局部变量或结构体中的字段时,同样的一般原则也适用。

尽可能使用通道端口语法是一个好的实践,因为编译器将能够更彻底地检查您是否编写了您想要的内容。

有趣的是,occam编程语言也具有等效的语法来标记通道的哪一端是哪一端。

英文:

A good way to think of channels is as pipes with two ends. One end is where the events flow in and the other where they flow out. So declaring a channel, e.g.

var c = make(chan int)

creates a channel as a whole - i.e. with both ends. Conversely,

func consume(c &lt;-chan int) {
    ...
}

defines a function with a channel input parameter - i.e. the readable end of a channel, and

func generate(c chan&lt;- int) {
    ...
}

defines a function with a channel output parameter - i.e. the writable end of a channel. Both these functions can have the whole channel passed as their actual parameter, or just the end they need.

The same general principle applies when channels are used as local variables or as fields in structs.

It's good practice to use the channel-end syntax wherever possible, because the compiler will be able to check more thoroughly that you've written what you intended.

Interestingly, the occam programming language also has equivalent syntax to mark which end of a channel is which.

答案3

得分: 0

虽然你可以声明一个实际的“只读”或“只写”通道变量,但这样做是没有用的,因为你不能对它们做任何操作。

“只读”和“只写”的语法是用于函数参数的。这种语法更像是C语言中的“const”或Ada语言中的“in”和“out”。

Go语言的通道也没有两个“端口”。UNIX管道有两个文件描述符,一个用于每个端口。而在Go语言中,同一个通道类型的变量既可以用于读取,也可以用于写入。

英文:

While you can declare an actual "read only" or "write only" channel variable, it's useless to do so, because you can't do anything with them.

The "read only" and "write only" syntax is for function parameters. This syntax is more like "const" in C or "in" and "out" in Ada.

Nor do Go channels have two "ends". UNIX pipes have two file descriptors, one for each end. The same variable of channel type is used for both reading and writing.

huangapple
  • 本文由 发表于 2012年12月28日 05:37:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/14061633.html
匿名

发表评论

匿名网友

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

确定