废话少叙,先上一段代码,猜猜预期的效果。
package main import (
"fmt"
) type student struct {
Name string
Age int
} func main() {
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
} fmt.Printf("%+v\n", m) for k, v := range m {
fmt.Printf("k:%s v:%v\n", k, v)
}
}
out:
map[zhou:0x42114e100 li:0x42114e100 wang:0x42114e100]
k:li v:&{wang 22}
k:wang v:&{wang 22}
k:zhou v:&{wang 22}
是不是很诧异,结果为什么不是预期的,map的值都是一个呢?
原因:for range每次产生的 k , v 都是一个值拷贝,不是 stus对应值得引用,故而会出现这种结果。
细节分析:
for _, stu := range stus {
m[stu.Name] = &stu
} // stu 是在 for中申请的一个局部变量,地址为:0x42114e100, 每次拷贝stus中对应的值。
// 迭代遍历之后,stu每次被重新赋值,而map记录的是 变量stu对应的地址值,故而不会产生预期的效果。
快速解决办法:
for _, stu := range stus {
a := stu
m[stu.Name] = &a
}
谨在此记录。