go vet 抱怨循环变量被 func 文字捕获

pka*_*mol -3 go

go github页面中记录的常见新手错误之一是忽略将循环变量作为参数传递给 goroutine(其中程序的输出可能会显示意外结果:

   for _, val := range values {
      go func() {
/* here is where go-vet complains loop variable v captured by func literal*/
          fmt.Println(val) 
      }()
   }

Run Code Online (Sandbox Code Playgroud)

很有可能当你运行这段代码时,你会看到每次迭代打印的最后一个元素,而不是按顺序打印的每个值,因为 goroutine 可能在循环之后才会开始执行。

因此,建议的解决方案是(如上所述)将实际循环 var 作为 goroutine 参数传递:

for _, val := range values {
    go func(val interface{}) {
        fmt.Println(val)
    }(val)
}

Run Code Online (Sandbox Code Playgroud)

那么go-vet在下面的例子中唠叨什么?

func main() {
    ch := make(chan int)

    for i := 0; i < 2; i++ {
        go func(emp int) {
            for range ch {
                rcv := <-ch
         /*  loop variable i captured by func literal */
                fmt.Printf("employee %d received signal %d\n", i, rcv)
            }
        }(i)
    }

}
Run Code Online (Sandbox Code Playgroud)

Bur*_*dar 5

这是一行:

fmt.Printf("employee %d received signal %d\n", i, rcv)
Run Code Online (Sandbox Code Playgroud)

在这里,使用emp代替i。您正在将循环变量传递emp给 goroutine,但您似乎忘记了使用它。