go语言之陷阱for range

在go语言中,遍历有两种方法,一种就是for的普通方法,还有一种就是for range的遍历,但是在使用for range时,如果使用不当,就会出现一些问题比如我们下面先来看一个例题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import "fmt"
type Student struct{
Name string
Age int
} //一个学生结构体
func main(){
m:=make(map[string]*Student) //声明一个映射
stus:=[]Student{
{"宋",22},
{"高",23},
{"徐",24},
{"李",25},
} //一个学生类切片
for _,stu:=range stus{
m[stu.Name]=&stu //遍历赋值给映射
}
for _,value:=range m{
fmt.Println(*value) //遍历打印出来
}
}

我们的代码是把stus这个结构体切片里面的内容用for range赋值给m映射,看起来代码好像没什么问题,一次循环赋值一次循环打印,那我们来看一下打印结果是什么

打印结果竟然是这样,为什么都是一样的呢,而且是结构体切片最后的一个元素,看下面这张图

这是因为我们第一次使用for range遍历的时候 我们是使用零时变量stu的地址来传给m的,而且零时变量stu每次的地址都是不会变的,所以一直到遍历最后一次就会把最后一个值的地址传给m,这就导致了m里面的值都是一样,我们可以试着来打印一下地址来看看

我们先来打印一下m看看

看到没,这四个地址竟然都是一样的,这就是因为用stu零时变量去地址去传的话地址都是一样的,那样传值就达不到预期的效果,所以一定要小心这个陷阱,那我们上面应该怎样改就可以完整的传值呢

看到没,我们可以在for range里面弄一个stu1来接受零时变量stu的值,然后取stu1的地址传值,这样就不会出错啦,我们来看看打印结果

这样我们每次的地址也不一样了,打印出来的结果也就正确达到预期的结果了,因为map是无序的所以打印出来也是无序的,切忌用for range的时候小心陷阱

-------------本文结束感谢您的阅读-------------

本文标题:go语言之陷阱for range

文章作者:Wuman

发布时间:2018年09月04日 - 12:09

最后更新:2018年09月05日 - 12:09

原始链接:http://yoursite.com/2018/09/04/go语言之陷阱for-range/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。