我在将指针分配给 map 时遇到问题。也许这是 Go 中的一个错误?或者也许我只是做错了什么。代码也在 Playground 上,https://play.golang.org/p/p0NosPtkptz
这里有一些 super 简化的代码可以说明问题。我正在创建一个名为 collections 的对象,其中有两个集合对象。然后我循环遍历这些集合并将它们分配给 map ,其中 map 中的键是集合 ID。
package main
import (
"fmt"
)
type collection struct {
ID string
Name string
}
type collections struct {
Collections []collection
}
type cache struct {
Index int
Collections map[string]*collection
}
func main() {
var c cache
c.Collections = make(map[string]*collection)
// Create 2 Collections
var col1, col2 collection
col1.ID = "aa"
col1.Name = "Text A"
col2.ID = "bb"
col2.Name = "Test B"
// Add to Collections
var cols collections
cols.Collections = append(cols.Collections, col1)
cols.Collections = append(cols.Collections, col2)
fmt.Println("DEBUG Collections Type", cols)
i := 0
for k, v := range cols.Collections {
c.Index = i
c.Collections[v.ID] = &v
fmt.Println("DEBUG k", k)
fmt.Println("DEBUG v", v)
i++
}
fmt.Println("Collection 1", c.Collections["aa"].ID)
fmt.Println("Collection 2", c.Collections["bb"].ID)
fmt.Println(c)
}
此 playground 代码的输出如下所示:
DEBUG Collections Type {[{aa Text A} {bb Test B}]}
DEBUG k 0
DEBUG v {aa Text A}
DEBUG k 1
DEBUG v {bb Test B}
Collection 1 bb
Collection 2 bb
{1 map[aa:0x1040a0f0 bb:0x1040a0f0]}
所以似乎 map 出于某种原因为每个条目获取相同的指针。所有“DEBUG”行都打印出我所期望的。但是,最后的三个打印行却没有。集合 1 应该是“aa”而不是“bb”。
最佳答案
当您将 &v
放入 c.Collections[v.ID]
时,您实际上是在为循环变量 v
分配相同的地址。
此地址最终包含列表的最后一个值。这就是为什么您要为所有 key 获取 bb Test B
。
打印这些值,您将看到相同的地址。
fmt.Printf("%p\n", c.Collections["aa"])
fmt.Printf("%p\n", c.Collections["bb"])
然后通过将它复制到循环范围内的一个新变量,问题就解决了。循环中的每一步都将一个新的唯一地址放入缓存。
for k, v := range cols.Collections {
coll := v
c.Collections[v.ID] = &coll
fmt.Println("DEBUG k", k)
fmt.Println("DEBUG v", v)
i++
}
关于pointers - 如何将指针分配给 Go map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48648000/