golang select语句中的case与default的优先级
问题描述:
我有一个运行for
循环的多个例程的应用程序,并且需要一种方法来指示这些for
循环中断,并测试是否发生超时情况。我一直在寻找到使用与select
语句共享信道来实现这一点,如下所示:golang select语句中的case与default的优先级
// elsewhere in the code, this channel is created, and passed below
done := make(chan struct{})
time.AfterFunc(timeout, func() { close(done) })
...
go func() {
Loop:
for {
select {
case <-done:
break Loop
default:
foo()
time.Sleep(1 * time.Second)
}
}
select {
case <-done:
panic("timed out!")
default:
// ok
}
}()
这是做到这一点的有效方法?我最关心的是选择的select
的分支可能是非确定性的,因此即使case
中的一个准备就绪,也可以选择default
。这可能吗?是否有任何文件表明匹配的case
保证优先于default
。值得关注的是,在done
关闭和/或报告成功后,即使发生超时,上面的for循环可能会循环多次。
答
The Go Programming Language Specification
在几个步骤的“选择”的声明收益的执行:
- 对于在声明中所有的情况下,渠道操作数接收操作和发送 语句的通道和右侧表达式按照源顺序精确评估一次,一旦输入 “select” tatement。结果是一组接收 或从中发送的通道,以及要发送的相应值。无论哪个(如果有的话) 通信操作被选择继续进行,将发生该评估中的任何一方的效果。尚未评估具有短变量声明或 赋值的RecvStmt左边的 表达式。
- 如果一个或多个通信可以继续进行,可以进行的单个通过一个统一的伪随机选择。 否则,如果存在默认情况,则选择该情况。如果 不是默认情况,则“选择”语句会阻塞,直到至少有一个通信可以继续进行。
- 除非所选情况是默认情况,否则将执行相应的通信操作。
- 如果选择的案例是带有短变量声明或赋值的RecvStmt,则会对左侧表达式进行求值并分配接收的值(或多个值) 。
- 执行所选案例的语句列表。
“我最关心的是,一个选择是 选择可能是不确定性,使默认可以选择甚至 如果的一个分支案件已经准备好了,这可能吗?“
否参见select
规范的第2步。
这也包括在内(不详细)[在围棋游览](https://tour.golang.org/concurrency/6)。 – Adrian