Golang可以通过:=声明的同时为变量赋值,还有变量的作用域也需要注意。for循环体中声明的变量作用域从for循环开始到花括号结束。给出一组学生的各科成绩,可能有重复的,学生的姓名唯一,按照姓名对分数求和。
packagemainimport"fmt"typestudentstruct{ScoreintNamestring}funcprintMap(mmap[string]*student){fork,v:=rangem{fmt.Println(k,v)}}funcmain(){s:=make([]student,0)s=append(s,student{1,"s1"})s=append(s,student{1,"s2"})s=append(s,student{2,"s1"})s=append(s,student{1,"s3"})m:=make(map[string]*student)foridx,v:=ranges{_,ok:=m[v.Name]if!ok{m[v.Name]=&v}else{m[v.Name].Score+=v.Score}fmt.Println(idx)printMap(m)}printMap(m)}
上面代码最终的输出:
s1&{1s3}s2&{1s3}s3&{1s3}
因为v的作用域在整个for循环,每次赋值的是v的地址,固定不变,所有value都被赋值为同一个值了。
改成如下代码:
packagemainimport"fmt"typestudentstruct{ScoreintNamestring}funcprintMap(mmap[string]*student){fork,v:=rangem{fmt.Println(k,v)}}funcmain(){s:=make([]student,0)s=append(s,student{1,"s1"})s=append(s,student{1,"s2"})s=append(s,student{2,"s1"})s=append(s,student{1,"s3"})m:=make(map[string]*student)foridx,v:=ranges{_,ok:=m[v.Name]if!ok{m[v.Name]=&s[idx]}else{m[v.Name].Score+=v.Score}}printMap(m)}
输出:
s1&{3s1}s2&{1s2}s3&{1s3}