这是《 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 <- <- valueStream是接收操作(receive operator)和send statement的串联。
receive运算符是一元运算符,因此具有最高优先级(Spec: Operators),而send语句是一条语句,并且不在运算符层次结构中。结果,c1 <- <- c2c1 <- (<-c2)相同。
因此,您的示例与以下示例相同:

takeStream <- (<-valueStream)
(请注意,任何其他解释都没有任何意义。)
和规格:发送语句:

必须先评估要发送的值,然后才能发送。因此,您的示例首先从valueStream接收一个值,然后在takeStream上发送该值...
...或者,如果此send语句(和receive运算符)独立存在,将会如此。
当在 select 语句中用作case的通信操作之一时,会发生以下情况:
Spec: Select statements:报价

所以,当你有这个:
select {
case <- done :
    return
case takeStream <- <- valueStream:
}
然后评估<-valueStream(从valueStream接收一个值)。如果操作被阻止,则整个select都将被阻止(即使done已关闭并因此准备从中接收)。
一旦从valueStream接收到一个值,则只有这样才能确定是否可以在takeStream上发送该值,如果其他情况也可以继续进行,则是否选择此case

07-24 20:54