在go中,循环变量使用相同的变量地址,只是每次迭代的时候不断更新其值。证明一下:
func main() {
sli := []int{1, 2, 3, 4, 5}
for _, v := range sli {
fmt.Printf("%x %d\n", &v, v)
}
}
c000014098 1
c000014098 2
c000014098 3
c000014098 4
c000014098 5
知道了它的特性后,就很容易理解go迭代变量捕获问题
var slice []func()
func main() {
sli := []int{1, 2, 3, 4, 5}
for _, v := range sli {
slice = append(slice, func() {
fmt.Println(v * v) // v的取值是最后一次迭代时候的值
})
}
for _, val := range slice {
val()
}
}
25
25
25
25
25
解决方法是把v 赋值给临时变量
var slice []func()
func main() {
sli := []int{1, 2, 3, 4, 5}
for _, v := range sli {
t := v // 先把值取出来
slice = append(slice, func() {
fmt.Println(t * t)
})
}
for _, val := range slice {
val()
}
}