欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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映射,看起来代码好像没什么问题,一次循环赋值一次循环打印,那我们来看一下打印结果是什么

go语言之陷阱for range
打印结果竟然是这样,为什么都是一样的呢,而且是结构体切片最后的一个元素,看下面这张图
go语言之陷阱for range
这是因为我们第一次使用for range遍历的时候 我们是使用零时变量stu的地址来传给m的,而且零时变量stu每次的地址都是不会变的,所以一直到遍历最后一次就会把最后一个值的地址传给m,这就导致了m里面的值都是一样,我们可以试着来打印一下地址来看看
go语言之陷阱for range
我们先来打印一下m看看
go语言之陷阱for range
看到没,这四个地址竟然都是一样的,这就是因为用stu零时变量去地址去传的话地址都是一样的,那样传值就达不到预期的效果,所以一定要小心这个陷阱,那我们上面应该怎样改就可以完整的传值呢
go语言之陷阱for range
看到没,我们可以在for range里面弄一个stu1来接受零时变量stu的值,然后取stu1的地址传值,这样就不会出错啦,我们来看看打印结果
go语言之陷阱for range
这样我们每次的地址也不一样了,打印出来的结果也就正确达到预期的结果了,因为map是无序的所以打印出来也是无序的,切忌用for range的时候小心陷阱