英文:
Pointer values rewritten in struct when appending to slice struct
问题
我今天遇到了一个奇怪的问题。
我一直在尝试从一个映射中获取值,并将其赋给一个结构体类型变量的切片。但是不知何故,结构体键中的指针值被重写了,原因不明。我编写了一个示例代码来演示这个问题。
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)
}
}
在结构体db
中,键PVals
的值在内存中被某种方式重写,导致输出为:
Main: xpos | PVal: &[-12 9 0]
Main: ypos | PVal: &[-12 9 0]
...理想情况下应该是
Main: xpos | PVal: &[123 234 543]
Main: ypos | PVal: &[-12 9 0]
如果我将PType.PVals
的类型从*[]string
更改为[]string
,问题就会得到解决。
在使用指针时,我做错了什么?
这是一个Playground链接,如果有帮助的话:https://play.golang.org/p/IVOUfTvoLt6
英文:
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
答案1
得分: 4
在一个for循环中,循环变量的地址是固定的。每次迭代都会重写循环变量。当你在映射中添加循环变量的地址时,你实际上添加的是在每次迭代中被重写的相同片段。因此,你最终得到的是一个值指向相同位置的映射。
如果没有指针,循环变量的副本将被放置在映射中。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论