【问题标题】:What does it mean when one channel uses two arrows to write to another channel in gogo中一个通道用两个箭头写入另一个通道是什么意思
【发布时间】:2020-05-18 17:01:03
【问题描述】:

这是来自 Go 中的并发一书的代码示例。在 select 块中是以下语句

case takeStream <- <- valueStream:

我不知道双箭头是做什么的,文中也没有解释。当我用

替换它时,输出会发生变化
case takeStream <- valueStream:

这显然是必要的

功能齐全:

func take(done<- chan interface{}, valueStream <- chan interface{}, num int) <- chan interface{}{
    takeStream := make ( chan interface{})
    go func() {
        defer close(takeStream)
        for i := 0; i < num; i ++ {
            select {
            case <- done :
                return
            case takeStream <- <- valueStream:
            }
        }
    }()

    return takeStream
}

已编辑:如果我理解正确,扩展的语句将是

i := 5
valueStream <- i
tmp <- valueStream
takeStream <- tmp

所以

takeStream <- <- valuesStream

是捷径

这就解释了为什么当我打电话时

fmt.Println(<-takeStream)

我得到了一些奇怪的数字 - 大概是 valueStream 的一些数字表示

谢谢!

【问题讨论】:

  • 请注意,takeStream &lt;- valueStream 发送valueStream 频道本身,而不是 valueStream 获得的值。

标签: go concurrency channels


【解决方案1】:

takeStream &lt;- &lt;- valueStream 是接收操作 (receive operator) 和 send statement 的串联。

接收运算符是一元运算符,因此具有最高优先级 (Spec: Operators),而发送语句是 语句,不属于运算符层次结构。因此,c1 &lt;- &lt;- c2c1 &lt;- (&lt;-c2) 相同。

所以你的例子是一样的:

takeStream <- (<-valueStream)

(请注意,任何其他解释都没有任何意义。)

和规范:发送声明:

通道和值表达式都在通信开始之前进行评估。

必须先评估要发送的值,然后才能发送。因此,您的示例首先从valueStream 接收一个值,然后将该值发送到takeStream...

...如果这个发送语句(和接收操作符)独立存在,它会是这样。

当在select 语句中用作case 的通信操作之一时,会发生以下情况:

引用Spec: Select statements:

“选择”语句的执行分几个步骤进行:

  1. 对于语句中的所有情况,在输入“select”语句时,接收操作的通道操作数以及发送语句的通道和右侧表达式仅按源顺序计算一次。结果是一组要接收或发送到的通道,以及要发送的相应值。无论选择哪种(如果有)通信操作进行,该评估中的任何副作用都会发生。 RecvStmt 左侧的带有短变量声明或赋值的表达式尚未计算。

[...]

所以当你有这个时:

select {
case <- done :
    return
case takeStream <- <- valueStream:
}

然后评估&lt;-valueStream(从valueStream 接收一个值)。如果操作是阻塞的,那么整个select 将阻塞(即使done 已关闭并准备好接收)。

一旦从valueStream接收到一个值,才会决定该值是否可以在takeStream上发送,如果其他情况也可以继续,是否选择这个case

  1. 如果一个或多个通信可以继续,则通过统一的伪随机选择选择一个可以继续的通信。否则,如果存在默认情况,则选择该情况。如果没有默认情况,“select”语句会阻塞,直到至少有一个通信可以继续。

【讨论】:

    猜你喜欢
    • 2015-03-16
    • 2021-09-13
    • 1970-01-01
    • 2020-04-09
    • 2012-01-11
    • 1970-01-01
    • 2014-03-16
    • 2013-05-01
    • 1970-01-01
    相关资源
    最近更新 更多