一个错误的使用Map示例(非常坑)
先看代码 package main import "fmt" type student struct { Name string Age int } func pase_student() { m := make(map[string]*student) stus := []student{ {Name: "zhou", Age: 24}, {Name: "wrh", Age: 22}, {Name: "qiang", Age: 21}, } for _, stu := range stus { m[stu.Name] = &stu } for _,va:= range m{ fmt.Println(va.Name,":",va) } } func main() { pase_student() }
x
1 package
main 2 3 import
"fmt" 4 5 type
student
struct { 6
Name
string 7
Age
int 8 } 9 10 func
pase_student () { 11
m :
make ( map [ string ] * student ) 12
stus :
[] student { 13
{ Name : "zhou" , Age : 24 }, 14
{ Name : "wrh" , Age : 22 }, 15
{ Name : "qiang" , Age : 21 }, 16
} 17
for
_ , stu :
range
stus { 18
m [ stu . Name ]
& stu 19
} 20 21
for
_ , va :
range
m { 22
fmt . Println ( va . Name , ":" , va ) 23
} 24 } 25 26 func
main () { 27
pase_student () 28 } 猜一下结果? //结果 qiang : &{qiang 21} qiang : &{qiang 21} qiang : &{qiang 21}
1 //结果 2 qiang : & { qiang
21 } 3 qiang : & { qiang
21 } 4 qiang : & { qiang
21 } ???????? 看看问题在哪里 ↓ ↓ ↓ ↓ ↓ for _, stu := range stus {//每次循环并不会为stu新开一块内存,而是修改stu指向的值!!! m[stu.Name] = &stu//这里的"stu"其实是值类型的,但是每次遍历都是存储 "stu" 的指针,虽然每次range操作是修改了stu对应的值,但是stu的指针地址是从来都没有变,所以这里不能绝对这么使用!!!!! }
1
for
_ , stu :
range
stus { //每次循环并不会为stu新开一块内存,而是修改stu指向的值!!! 2
m [ stu . Name ]
& stu //这里的"stu"其实是值类型的,但是每次遍历都是存储 "stu" 的指针,虽然每次range操作是修改了stu对应的值,但是stu的指针地址是从来都没有变,所以这里不能绝对这么使用!!!!! 3
} //正确的思路(1) *推荐 : 既然用了指针就要用到底 package main import "fmt" type student struct { Name string Age int } func pase_student() { m := make(map[string]*student) stus := []*student{//这里的student使用了指针,毕竟用指针就要用到底嘛 {Name: "zhou", Age: 24}, {Name: "wrh", Age: 22}, {Name: "qiang", Age: 21}, } for _, stu := range stus { m[stu.Name] = stu } for _,va:= range m{ fmt.Println(va.Name,":",*va)//输出的时候使用了指针 } } func main() { pase_student() } //结果 zhou : {zhou 24} wrh : {wrh 22} qiang : {qiang 21} //正确的思路(2) : 既然不用指针,就都不要用指针,全部传数值! package main import "fmt" type student struct { Name string Age int } func pase_student() { m := make(map[string]student) stus := []student{ {Name: "zhou", Age: 24}, {Name: "wrh", Age: 22}, {Name: "qiang", Age: 21}, } for _, stu := range stus { m[stu.Name] = stu//这里的"stu"其实是值,但是每次遍历都是存储 "stu" 的指针,虽然每次range操作是修改了stu对应的值,但是stu的指针地址是从来都没有变,所以这里不能这么使用!!!!! } for _,va:= range m{ fmt.Println(va.Name,":",va) } } func main() { pase_student() } //结果 zhou : {zhou 24} wrh : {wrh 22} qiang : {qiang 21}
x
1 //正确的思路(1) *推荐 : 既然用了指针就要用到底 2 package
main 3 4 import
"fmt" 5 6 type
student
struct { 7
Name
string 8
Age
int 9 } 10 11 func
pase_student () { 12
m :
make ( map [ string ] * student ) 13
stus :
[] * student { //这里的student使用了指针,毕竟用指针就要用到底嘛 14
{ Name : "zhou" , Age : 24 }, 15
{ Name : "wrh" , Age : 22 }, 16
{ Name : "qiang" , Age : 21 }, 17
} 18
for
_ , stu :
range
stus { 19
m [ stu . Name ]
stu 20
} 21 22
for
_ , va :
range
m { 23
fmt . Println ( va . Name , ":" , * va ) //输出的时候使用了指针 24
} 25 } 26 27 func
main () { 28
pase_student () 29 } 30 //结果 31 zhou : { zhou
24 } 32 wrh : { wrh
22 } 33 qiang : { qiang
21 } 34 35 //正确的思路(2) : 既然不用指针,就都不要用指针,全部传数值! 36 package
main 37 38 import
"fmt" 39 40 type
student
struct { 41
Name
string 42
Age
int 43 } 44 45 func
pase_student () { 46
m :
make ( map [ string ] student ) 47
stus :
[] student { 48
{ Name : "zhou" , Age : 24 }, 49
{ Name : "wrh" , Age : 22 }, 50
{ Name : "qiang" , Age : 21 }, 51
} 52
for
_ , stu :
range
stus { 53
m [ stu . Name ]
stu //这里的"stu"其实是值,但是每次遍历都是存储 "stu" 的指针,虽然每次range操作是修改了stu对应的值,但是stu的指针地址是从来都没有变,所以这里不能这么使用!!!!! 54
} 55 56
for
_ , va :
range
m { 57
fmt . Println ( va . Name , ":" , va ) 58
} 59 } 60 61 func
main () { 62
pase_student () 63 } 64 //结果 65 zhou : { zhou
24 } 66 wrh : { wrh
22 } 67 qiang : { qiang
21 }