在Go中,何时在多值分配中复制值?

时间:2017-07-10 07:28:26

标签: go return variable-assignment specifications

考虑以下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上的规范部分没有说明在这种情况下它何时阻止线程。

1 个答案:

答案 0 :(得分:1)

根据order of evaluation的规范部分,这样的语句中的函数和接收操作从左到右进行评估:

  

例如,在(函数 - 本地)赋值

y[f()], ok = g(h(), i()+x[j()], <-c), k()
     

函数调用和通信以f()h()i()j()<-cg()和{的顺序发生{1}}。 但是,未指定与k()的评估和索引以及x的评估相比较的事件顺序。

但正如强调句中所述,未指定变量评估的顺序。

该部分提供了另一个示例,使其更加清晰:

y

因此,虽然行为符合要求,但遗憾的是没有指定,也不能依赖。