Go语言中的循环与指针问题:为什么v.name都是“博客”?

Go语言中的循环与指针问题:为什么v.name都是“博客”?

go语言循环指针陷阱:详解v.name全为“博客”的原因

Go语言中的for…range循环和指针结合使用时,容易出现一些令人困惑的问题。本文通过一个例子,深入剖析for…range循环的机制以及指针的使用,解释为什么代码输出结果全为“博客”。

以下代码片段展示了这个问题:

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)     } }

运行这段代码,输出结果将全部是博客。这是因为for…range循环中的stu变量并非每次迭代都创建一个新的变量。它是一个循环变量,其内存地址在整个循环过程中保持不变。 因此,&stu始终指向同一个内存地址。每次迭代都将这个相同的地址赋值给map中的值,最终map中所有指针都指向了最后一个stu变量,即{name: “博客”, age: 28}。

解决方法:创建新的变量副本

立即学习go语言免费学习笔记(深入)”;

为了避免这个问题,需要在每次迭代中创建stu的副本,而不是直接使用其地址:

for _, stu := range stus {     s := stu // 创建stu的副本     m[stu.name] = &s }

通过创建新的变量s,m[stu.name] = &s 现在指向的是s的内存地址,而s在每次迭代中都是一个新的变量,从而解决了指针指向同一内存地址的问题,最终输出结果将正确反映每个学生的姓名。

理解for…range循环的机制以及指针的特性,对于编写高效且正确的Go代码至关重要。 避免此类陷阱的关键在于,在循环中使用指针时,要确保每个指针都指向不同的内存地址。

以上就是Go语言中的循环与指针问题:

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享