一 问题来源
最近做的一个项目中 ,在使用for循环,遍历用户信息时,遇到一个坑,觉得很容易用错 ,故写下这篇文章来警示自己。
二 问题描述
简单的说,就是我在使用for range对slice进行append地址操作,append完之后,遍历结果,发现结果值都一样。用代码示例,如下:
func main() {
var out []*int
for i := 0; i < 3; i++ {
out = append(out, &i)
}
fmt.Println("Values:", *out[0], *out[1], *out[2])
fmt.Println("Addresses:", out[0], out[1], out[2])
}
得到的结果如下:
Values: 3 3 3
Addresses: 0xc000016050 0xc000016050 0xc000016050
三 出现的原因
在for range的过程中,变量i只被创建了一次,变量i有自己的空间内存且地址在for循环过程中不变,循环过程中每次将i进行值传递。这样append到out里面的是i的地址,且每次都一样。循环到最后一个的时候,out里面的值就跟最后的一个相同了。
四 解决策略
最简单的办法就是把变量i赋值到一个新的变量上,这样就不会出现该问题了
func main() {
var out []*int
for i := 0; i < 3; i++
i := i
out = append(out, &i)
}
fmt.Println("Values:", *out[0], *out[1], *out[2])
fmt.Println("Addresses:", out[0], out[1], out[2])
}
Values: 0 1 2
Addresses: 0xc00007e020 0xc00007e028 0xc00007e030