废话少叙,先上一段代码,猜猜预期的效果。
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 ", m) for k, v := range m { fmt.Printf("k:%s v:%v ", 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 }
谨在此记录。