Golang - 带指针的地图的空间效率

时间:2016-05-06 18:58:51

标签: pointers dictionary memory go space-complexity

我对指针的熟悉程度最低,但它们似乎是重用内存的好方法,并避免制作额外的对象副本。

假设我有struct

type MyObject struct {
  field1 int
  field2 string
  field3 []string // some long list of long strings
}

我希望有两个maps允许通过字段值有效查找相应的对象

myField1Map := make(map[int]*MyObject)
myField2Map := make(map[string]*MyObject)

OR

myField1Map := make(map[int]MyObject)
myField2Map := make(map[string]MyObject)

假设我选择前者

myObj1 := new(MyObject)
myObj1.field1 = 1
myObj1.field2 = "Mufasaaaaa"
myObj1.field3 = []string{// lots and lots of long strings}

myField1Map[myObj1.field1] = myObj1
myField2Map[myObj1.field2] = myObj1

在空间效率方面我的权衡是什么?在我看来,我正在节省空间,因为两个地图都指向内存中的同一个对象。

很酷的是,我在Go Playground中设置了一个玩具问题。我可以在我的某个地图中更改某个值的字段,它将显示在另一个地图中。如果,假设其中一个映射是指向对象的指针值的主键,这似乎是一个很好的奖励。

有人可以澄清这是否是思考指针和空间的正确方法。这也是一种常见做法吗?我在Go作弊吗?

1 个答案:

答案 0 :(得分:2)

我不能说这是否是一种常见的做法,但它根本就不是作弊。 考虑在go中复制结构,因此在复制整个结构时可能会占用大量空间。

但请注意,切片隐式指向底层数组。因此,如果您的结构具有field3的切片类型,您最终只会复制几个值,而实际的保存不会那么多 - 在这种情况下。

尽管如此,我更喜欢带指针的解决方案。如果一个值由两个不同的位置访问,在概念上更容易指向一个值,并且在你修改一个字段的情况下,你也不必更新相应的另一个字段。 (编辑对不起,我没有读到你自己想出来的这个:))