目前我正在存储一个地图,其中键是一个结构(MyIntC)。我想将地图中的所有关键字检索为切片。切片将是指向地图键的指针。这样就没有多个密钥的副本。
当我在这里尝试(https://play.golang.org/p/bclmCh_YV5)时,它无效。
切片中的所有元素都将指向迭代的最后一个map键元素。
为什么会这样?我怎么能克服这个?
注意:我怀疑它与Slice of structs vs a slice of pointers to structs非常相似,我总是使用本地变量地址。
感谢。
答案 0 :(得分:2)
您对范围循环中与k
相关的问题是正确的。 k
是一个局部变量,在每次迭代中,您只需将相同的指针地址添加到slice
。
您始终可以使用指向MyIntC
的指针作为地图键。
// ...
slice := make([]*MyIntC,0, 5)
// ...
mapInts := make(map[*MyIntC]string)
// ...
for k, _ := range mapInts {
slice = append(slice, k)
}
// ...
答案 1 :(得分:0)
您无法获得地图键的地址。这是为了防止您修改键,因为这样做可能会影响值在地图内的位置。 此外,Go 还不允许 getting the address of a map value。
注意将指针存储为映射键的“解决方案”,因为这样做的语义非常不同 - 指向键的指针的值将用于查找和唯一性,而不是键本身的值。
type MyIntC struct {
MyInt int
}
func main() {
myInt5 := &MyIntC{MyInt: 50}
mapInts := make(map[*MyIntC]string)
mapInts[myInt5] = "something 50"
_, found := mapInts[&MyIntC{MyInt: 50}]
fmt.Println(found)
}
打印 false
。
有关详细信息,请参阅 Go Gotcha: Struct pointers as map keys。
真正的解决方案是“接受它”,即接受这样一个事实,即在迭代地图时您将获得密钥的副本。毕竟,密钥应该简短且唯一,因此复制它们应该不是问题。