Go循环中指针问题:v.name为何都显示“博客”?
Go语言中的循环与指针问题:为什么v.name都是“博客”?在Go语言编程中,有时候会遇到一些看似奇怪的问题,�...

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}。
解决方法:创建新的变量副本
为了避免这个问题,需要在每次迭代中创建stu的副本,而不是直接使用其地址:
for _, stu := range stus {
s := stu // 创建stu的副本
m[stu.name] = &s
}
通过创建新的变量s,m[stu.name] = &s 现在指向的是s的内存地址,而s在每次迭代中都是一个新的变量,从而解决了指针指向同一内存地址的问题,最终输出结果将正确反映每个学生的姓名。
理解for...range循环的机制以及指针的特性,对于编写高效且正确的Go代码至关重要。 避免此类陷阱的关键在于,在循环中使用指针时,要确保每个指针都指向不同的内存地址。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















