pointers - 如何将指针分配给 Go map

标签 pointers dictionary go

我在将指针分配给 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/

相关文章:

c - 如何使用相同的函数初始化相似的结构?

Java - 平铺 map 对象

linux - 如何在 journalctl 之外分析 journalctl 日志?

jquery - 使用 GoLang mgo 在 MongoDb 中保存 pdf

c++ - 如何阻止这种内存泄漏

c++ - 通过指针传递的区别-C++

c++ - 指向指针的多个指针

python - 根据带有一个嵌套字典的键过滤字典列表

python - 获取所有子词典的key

performance - opengl3 20k Sprite 帧率慢?