go - Pointer values rewritten in struct when appending to slice struct
问题描述
I've been dealing with a weird issue today.
So, I've been trying to get values from a map and assign to a slice of struct type variable. But somehow the pointer value in a struct key gets rewritten, not sure why. I've written a sample code to demonstrate the problem.
package main
import "fmt"
type PType []struct {
Main string
PVals *[]string
}
var mkey = map[string][]string{
"xpos": {"123", "234", "543"},
"ypos": {"-12", "9", "0"},
}
func main() {
var db PType
for mval, pval := range mkey {
db = append(db, struct {
Main string
PVals *[]string
}{
Main: mval,
PVals: &pval,
})
}
for _, x := range db {
fmt.Printf("Main: %+v | PVal: %+v\n", x.Main, x.PVals)
}
}
The value of the key PVals
in the struct db
gets overwritten somehow in memory resulting in the output:
Main: xpos | PVal: &[-12 9 0]
Main: ypos | PVal: &[-12 9 0]
...which should ideally be
Main: xpos | PVal: &[123 234 543]
Main: ypos | PVal: &[-12 9 0]
The problem is fixed if I change the type of the PType.PVals
from *[]string
to just []string
.
What am I doing wrong keeping pointers?
Here a playground link if that helps: https://play.golang.org/p/IVOUfTvoLt6
解决方案
In a for loop, the addresses of the loop variables are fixed. Every iteration rewrites the loop variables. When you add the address of the loop variable in the maps, you add the same slice that gets overwritten at each iteration. So you end up with a map whose values are pointing to the same location.
Without the pointer, a copy of the loop variable is placed in the map.
推荐阅读
- python-3.x - 在python中,我如何为来自串行的每一行输出添加时间戳?
- typescript - 使用装饰器强制类的所有方法具有特定签名
- javascript - 数据表未更新 where 子句
- pandas - 熊猫在行参加条件下连接部分索引
- php - 接收外部推送的 Web 服务
- tensorflow - 使用seq2seq模型(如transformer)进行命名实体识别?
- c# - 具有可为空属性的多个条件的 EF Core 联接表
- javascript - 如何使用自己的证书为 webpack-dev-server 启用 https?
- python-3.x - TypeError:“位置”类型的对象不是 JSON 可序列化的
- python - 按元素过滤列表数据帧