無論是普通的for循環(huán)开仰,還是for range遍歷其定義的局部變量都會重復(fù)使用
- 且看下例
type person struct {
name string
age int
}
func main() {
ma := []person{
person{"zhangsan", 11},
person{"lisi", 13},
person{"wangwu", 12},
}
mb := []*person{}
for _, v := range ma {
mb = append(mb, &v)
}
fmt.Println(mb[0], mb[1], mb[2])
}
輸出結(jié)果:
&{wangwu 12} &{wangwu 12} &{wangwu 12}
Process finished with exit code 0
為什么是這個結(jié)果呢丧裁, 因為例子中直接取了&v的地址讼撒,前文所說, for中定義的局部變量都會重復(fù)使用再菊, 所以導(dǎo)致mb中的三個結(jié)果都指向了v的地址轧坎。
那么如何避免此類問題:
- 在遍歷中不要使用局部變量的地址進行操作宏邮, 如下:
// 上例中的for range循環(huán)內(nèi)部改為:
for _, v := range ma {
val := v
mb = append(mb, &val)
}
- 上例ma變量定義成[]*person 類型, 然后 在for range中可以進行直接賦值操作:
func main() {
ma := []*person{
&person{"zhangsan", 11},
&person{"lisi", 13},
&person{"wangwu", 12},
}
mb := []*person{}
for _, v := range ma {
val := v
mb = append(mb, val)
}
fmt.Println(mb[0], mb[1], mb[2])
}