美文网首页golang
golang很容易踩的for range的坑

golang很容易踩的for range的坑

作者: 竹一先生_阳明学子 | 来源:发表于2019-12-18 22:05 被阅读0次

    背景介绍

    for range一个很容易踩的坑,记录一下。

    现象描述

    有问题的代码如下:

    arr := []int{1, 2, 3}
    
    myMap := make(map[int]*int)
    for i, v := range arr {
        myMap[i] = &v
    }
    
    for _, v := range myMap {
        fmt.Println(*v)
    }
    

    上面这段代码执行结果是:

    3
    3
    3
    

    按理不是应该打印下面这个结果吗:

    1
    2
    3
    

    为什么结果不符合预期呢?

    合理解释

    上面的问题,就是for range有点坑的地方:

    对于代码

    for i, v := range arr
    

    实际执行是:

    1. 声明变量i,v;
    2. 遍历arr,将第一个值1赋值给v,将v的地址myMap[0];
    3. 再将第二个值2赋值给v,将v的地址myMap[1];
    4. 再将第三个值3赋值给v,将v的地址myMap[2];

    所以可以看到:
    myMap[0]、myMap[1]、myMap[2]实际存储的都是同一个地址,
    都是 遍历arr前声明好的变量v的地址,
    所以打印出来的结果都是 最后放入v中的值3.

    正确做法

    知道了问题的本质原因后,解决方法也显而易见了:
    将每次遍历的值赋值给新的变量,再将新变量的地址赋值给myMap[i];

    代码

    arr := []int{1, 2, 3}
    
    myMap := make(map[int]*int)
    for i, v := range arr {
        vTmp := v // 关键!!!
        myMap[i] = &vTmp
    }
    
    for _, v := range myMap {
        fmt.Println(*v)
    }
    

    喜欢的话,关注我的公众号哦

    image.png

    相关文章

      网友评论

        本文标题:golang很容易踩的for range的坑

        本文链接:https://www.haomeiwen.com/subject/hlrpnctx.html