这是《 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 <- <- c2
与c1 <- (<-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
。