【问题标题】:Why does the channel type have a '<-' in it?为什么频道类型中有一个'<-'?
【发布时间】:2012-12-27 21:37:17
【问题描述】:

这行得通。

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

但事实并非如此。

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

为什么我的频道类型声明中需要&lt;-?我认为&lt;- 用于写入或读取通道。为什么会出现在一个类型中?

【问题讨论】:

    标签: go


    【解决方案1】:

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

    指示通道方向是用

    所以&lt;-chan time.Time 中的&lt;- 是类型的一部分,

    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) 返回一个只读通道。

    阅读更多语言规范here

    【讨论】:

    • @david-faux,还请注意,您可以只使用 tick := time.Tick(1e8) 并让编译器自动为 tick 派生正确的类型。这种方法也大大减少了混乱。
    【解决方案2】:

    将渠道视为两端的管道。一端是事件流入的地方,另一端是事件流出的地方。所以声明一个频道,例如

    var c = make(chan int)
    

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

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

    使用通道输入参数定义函数 - 即通道的可读端,并且

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

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多