11

这行得通。

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

然而,事实并非如此。

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

为什么我<-的频道类型声明中需要一个?我认为那<-是为了写入或从频道读取。为什么它会出现在一个类型中?

4

3 回答 3

19

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

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

所以<-in<-chan time.Time是类型的一部分,

chan   time.Time  //Would be a read/writable channel
chan<- time.Time  // Would be a write only channel
<-chan time.Time  // Would be a read only channel

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

在此处阅读语言规范的更多信息

于 2012-12-27T21:44:41.497 回答
4

将通道视为具有两端的管道的一个好方法。一端是事件流入的地方,另一端是事件流出的地方。所以声明一个通道,例如

var c = make(chan int)

创建一个整体的通道 - 即两端。反过来,

func consume(c <-chan int) {
    ...
}

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

func generate(c chan<- int) {
    ...
}

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

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

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

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

于 2012-12-28T23:59:17.473 回答
0

虽然您可以声明一个实际的“只读”或“只写”通道变量,但这样做是没有用的,因为您无法对它们做任何事情。

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

Go 频道也没有两个“端”。UNIX 管道有两个文件描述符,每一端一个。相同的通道类型变量用于读取和写入。

于 2013-05-22T04:41:19.253 回答