以下代码有什么问题,说明原因。
type student struct {
Name string
Age int
}
func pase_student() {
m := make(map[string]*student)
stus := []student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for _, stu := range stus {
m[stu.Name] = &stu
}
}
最后的结果是
map[li:0xc00008a000 wang:0xc00008a000 zhou:0xc00008a000]
气不气,最后Map中的student指针全都指向了同一个地址,为什么呢?
我们在代码打印一些信息
func pase_student() {
stu1 := student{Name: "zhou", Age: 24}
stu2 := student{Name: "li", Age: 23}
stu3 := student{Name: "wang", Age: 22}
println(&stu1,&stu2,&stu3)
stus := []student{stu1, stu2, stu3}
for index, stu := range stus {
println(index, "=", &stu)
}
}
输出结果
0xc000034700 0xc0000346e8 0xc0000346d0
0 = 0xc000034718
1 = 0xc000034718
2 = 0xc000034718
可以发现在range中打印的stu指针都是同一个,而且不是前面初始化的3个stu中的任何一个地址
可以这么理解,range是遍历这个slice,range申请了一块内存来存放元素,每个元素都会复制到这块地址上,所以在range中打印的地址都是range申请的这块内存地址,最后这块地址的值就是slice最后一个元素的值
而正确的方式是
for i:= 0;i < len(stus); i++ {
m[stus[i].Name] = &stus[i]
}
for k,v:= range m {
println(k,"=>",v.Name)
}