type student struct {
name string
age int
}
func main() {
m := make(map[string]*student)
stus := []student{
{name: "小王子", age: 18},
{name: "娜扎", age: 23},
{name: "大王八", age: 9000},
}
for _, stu := range stus {
m[stu.name] = &stu
}
for k, v := range m {
fmt.Println(k, "=>", v.name)
}
}
返回异常值:
娜扎 => 大王八
大王八 => 大王八
小王子 => 大王八
正确应该返回:
娜扎 => 娜扎
大王八 => 大王八
小王子 => 小王子
修改后:
type student struct {
name string
age int
}
func main() {
m := make(map[string]*student)
stus := []student{
{name: "小王子", age: 18},
{name: "娜扎", age: 23},
{name: "大王八", age: 9000},
}
for _, stu := range stus {
s := stu
m[stu.name] = &s
}
for k, v := range m {
fmt.Println(k, "=>", v.name)
}
}
原因分析:
来看一下for循环输出的结果:
for _, stu := range stus {
m[stu.name] = &stu
fmt.Println(m)
}
for k, v := range m {
fmt.Println(k)
fmt.Println(v)
fmt.Println(k, "=>", v.name)
}
返回值:
map[小王子:0xc000004078]
map[娜扎:0xc000004078 小王子:0xc000004078]
map[大王八:0xc000004078 娜扎:0xc000004078 小王子:0xc000004078]
小王子
&{大王八 9000}
小王子 => 大王八
娜扎
&{大王八 9000}
娜扎 => 大王八
大王八
&{大王八 9000}
大王八 => 大王八
结果:
可以看到m输出的值中有固定的地址0xc000004078(每个人运行出来的地址会有不同),所以代表m的v值是相同的,
所以0xc000004078这个地址表示的是"大王八 9000"这个值
原因:
for 循环每次产生的 key 和 value 其实是对应的 stus 里面值的拷贝,不是对应的 stus 里面的值的引用,
所以出现了这种问题
原因:
stu 是 stus 在for循环中申请的一个局部变量,每次循环都会拷贝 stus 中对应的值 stu。迭代遍历之后,
stu 每次会被重新赋值,而在 m 这个 map 中记录的 value 只不过是 最后一次拷贝的stu 的内存地址