go语言之陷阱for range

在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的时候小心陷阱

猜你喜欢

转载自blog.csdn.net/sgsgy5/article/details/81812591