我在下面运行了几次代码,有时在“test2”之后打印“test”
那是为什么?
我认为“真实”首先被发送到“测试”。
package main
import "log"
import "time"
func main() {
test := make(chan bool, 1)
test2 := make(chan bool, 1)
go func() {
for {
select {
case <-test:
log.Println("test")
case <-test2:
log.Println("test2")
}
}
}()
time.Sleep(3 * time.Second)
test <- true
test2 <- true
time.Sleep(1)
}
编辑2014/7/27:
在阅读article之后,我认为“test&lt; - true”和“test2&lt; - true”中的每一个都可能是“之前发生”或“发生之后”或“发生同时发生”。
答案 0 :(得分:1)
“如果一个或多个通信可以进行,则可以通过统一的伪随机选择来选择可以继续进行的单个通信。”您正在看到统一的伪随机选择。
The Go Programming Language Specification
执行“select”语句分几步进行:
1)对于语句中的所有情况,接收的通道操作数 操作以及发送的通道和右侧表达式 语句在输入时按源顺序精确评估一次 “选择”声明。结果是一组要接收的通道 from或send to,以及要发送的相应值。任何一方 无论哪个(如果有的话)都会发生评估中的影响 选择通信操作以继续。表达方式 带有短变量声明的RecvStmt的左侧或 作业尚未评估。
2)如果一个或多个通信可以进行,则单个通信 可以通过统一的伪随机选择来选择。 否则,如果存在默认情况,则选择该情况。如果有 没有默认情况,“select”语句会阻塞至少一个 通讯可以继续。
3)除非所选案例是默认案例,否则各自 通讯操作已执行。
4)如果所选案例是具有短变量的RecvStmt 声明或作业,左侧的表达是 评估并分配收到的值(或值)。
5)执行所选案例的陈述清单。
由于nil通道上的通信永远无法进行,因此请选择 只有零通道,没有默认情况下永久阻止。