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)
这是一行:
fmt.Printf("employee %d received signal %d\n", i, rcv)
Run Code Online (Sandbox Code Playgroud)
在这里,使用emp代替i。您正在将循环变量传递emp给 goroutine,但您似乎忘记了使用它。