Go语言向结构体切片追加元素时内部指针值被覆盖问题求解
问题根因
这是Go语言for range循环的经典变量复用陷阱:
for mval, pval := range mkey中定义的pval是循环的临时遍历变量,整个循环生命周期内只会分配一次内存地址,每次迭代仅覆盖该地址上存储的切片值,不会创建新的独立变量。- 你代码中每次给
PVals赋值时取的都是&pval,也就是同一个临时变量的内存地址,因此所有结构体的PVals指针最终都指向同一块内存。循环结束后,这块内存中存储的是最后一次迭代的ypos对应切片值,所以输出的所有PVals结果都和最后一组值一致。
为什么改为值类型后问题修复
当你把PVals的类型从*[]string改为值类型[]string时,赋值操作是直接拷贝当前pval的切片值到结构体字段,而非存储共用的地址,每次迭代都会保存当前值的独立拷贝,自然不会出现后续覆盖的问题。
保留指针类型的修复方案
如果业务需要保留PVals的指针类型,只需在循环内部每次迭代时创建一个独立的临时变量存储当前的切片值,再取新变量的地址赋值即可:
func main() { var db PType for mval, pval := range mkey { // 每次迭代创建独立的临时变量,分配新的内存地址 currPVal := pval db = append(db, struct { Main string PVals *[]string }{ Main: mval, PVals: &currPVal, }) } for _, x := range db { fmt.Printf("Main: %+v | PVal: %+v\n", x.Main, x.PVals) } }
内容的提问来源于stack exchange,提问作者0xInfection
相关产品推荐
相关产品推荐

