go 结构体相关试题


go语言学习到结构体部分,有个以下练习,是和指针(或者地址)相关的

代码如下

type student struct {
    name string
    age  int
}

func main() {
    m := make(map[string]*student)
    stus := []student{
        {name: "pprof.cn", age: 18},
        {name: "测试", age: 23},
        {name: "博客", age: 28},
    }

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

分析如上代码想要实现的功能以及存在的问题。如何改进?

其实上述代码想要用stus结构体数组来初始化map类型的m.

但是实际的运行结果是

发现全部的值都为‘’博客‘’。

这是因为在第一个for循环中,m的中插入的键值对的值都是&stu。由于range是值拷贝,也就是说最后stu中剩下的只有数组遍历的最后一个拷贝“博客”。m的每个值都是指向stu的内存地址。所以导致了这种结果。

改进代码如下

func main() {
	m := make(map[string]*student)
	stus := []student{
		{name: "pprof.cn", age: 18},
		{name: "测试", age: 23},
		{name: "博客", age: 28},
	}

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