考虑以下Go函数(playground),该函数使用Go 1.8进行评估:
func f() (int, bool) {
i := 0
c := make(chan bool)
go func() {
time.Sleep(1 * time.Second)
i = 1
c <- true
}()
// In practice, `i` will always be 0 here.
return i, <-c // returns 1, true
}
如评论中所述,在 i
产生值后,该函数似乎始终复制c
。因为这在遇到return语句后约1秒发生,这不是我所期望的。
如果在回报中反转了价值指令,并且如果通过转让替换了回报,则行为相同。
请注意,我并没有声称这种行为是错误的 - 只是出乎意料。事实上,这几乎总是你想要发生的事情。
因此,问题是这个可以依赖的预期/指定行为吗?
receive operator上的规范部分没有说明在这种情况下它何时阻止线程。
答案 0 :(得分:1)
根据order of evaluation的规范部分,这样的语句中的函数和接收操作从左到右进行评估:
例如,在(函数 - 本地)赋值
中y[f()], ok = g(h(), i()+x[j()], <-c), k()
函数调用和通信以
f()
,h()
,i()
,j()
,<-c
,g()
和{的顺序发生{1}}。 但是,未指定与k()
的评估和索引以及x
的评估相比较的事件顺序。
但正如强调句中所述,未指定变量评估的顺序。
该部分提供了另一个示例,使其更加清晰:
y
因此,虽然行为符合要求,但遗憾的是没有指定,也不能依赖。