学习go的第7天遇到的一个小题分析

题目代码:

type student struct {
    name string
    age  int
}

func main() {
    m := make(map[string]*student)
    stus := []student{
        {name: "小王子", age: 18},
        {name: "娜扎", age: 23},
        {name: "大王八", age: 9000},
    }

    for _, stu := range stus {
        m[stu.name] = &stu
    }
    for k, v := range m {
        fmt.Println(k, "=>", v.name)
    }
}

预期的输出结果:

娜扎 => 娜扎
大王八 => 大王八
小王子 => 小王子

实际输出结果:

娜扎 => 大王八
大王八 => 大王八
小王子 => 大王八

题目分析:

学习go的第7天遇到的一个小题分析

本作品采用《CC 协议》,转载必须注明作者和本文链接
CunWang@Ch
讨论数量: 7

看几遍没发现问题的产生的原因所在 :joy:

2年前 评论
村望老弟 (楼主) 2年前

其实就是每次循环给map新增键值对的时候,那个新键值对的值,都是内部变量value的指针,问题就是出在这里的啦哈哈~

2年前 评论
giao哥

就是 for _, v := range items 中 v 每次迭代都是使用相同的地址去接受的。所以打印的结果是 大王八 @

2年前 评论
村望老弟 (楼主) 2年前

file

问题出现在这里,m 这个map里每个键值对中存储的都是stu变量的指针,指针指向的内存空间存储的内容是随着循环改变的,所有指针指向的内存空间存储的就是最后一次stus切片的指针,可以研究一下切片

2年前 评论

娜扎:你礼貌吗?

2年前 评论

所以正确的答案是什么呢?

2年前 评论
村望老弟 (楼主) 2年前

正确答案应该不取地址吗

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!