go语言之陷阱for range
程序员文章站
2022-07-14 13:29:38
...
|版权声明:本文为博主原创文章,未经博主允许不得转载。博客地址:https://blog.csdn.net/sgsgy5
在go语言中,遍历有两种方法,一种就是for的普通方法,还有一种就是for range的遍历,但是在使用for range时,如果使用不当,就会出现一些问题比如我们下面先来看一个例题
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的时候小心陷阱
推荐阅读