我试图理解如何操纵Go中的数据结构及其指针方法(带有副本或引用)。
我的代码在Go Playground上,在这里:https://play.golang.org/p/j_06RS5Xcz
我制作了一个结构切片的地图,里面还有一片其他东西。
这里:
type Item struct {
Name string
Description string
}
type Entity struct {
Base Item
Others []Item
}
var database map[int][]Entity
func main() {
database = make(map[int][]Entity)
database[1] = []Entity{}
e1 := Entity{}
e1.Base = Item{"A", "aaa"}
e1.Others = []Item{}
database[1] = append(database[1], e1)
// later, I want to add other items to my entity
e1.Others = append(e1.Others, Item{"B", "bbb"})
// other items field is empty
fmt.Println(database)
}
// prints: map[1:[{{A aaa} []}]]
我想在我的程序中稍后添加其他项目。似乎我必须使用指针来解决这个问题,但我不知道如何。
我的实体应该是这样吗?
type Entity struct {
Base Item
Others *[]Item
}
如果是这样,我应该如何追加物品呢?像这样?
*e1.Others = append(*e1.Others, Item{"B", "bbb"})
如果还有其他问题的空间......我也不清楚我是否必须这样做。在database[1] = []Entity{}
之前执行:database[1] = append(database[1], e1)
或者我可以在这种情况下添加e1.Others = []Item{}
。我在<p style="width:300px">
<input class="mdl-slider mdl-js-slider" type="range" id="s1" min="0" max="10" value="4" step="2">
</p>
上尝试了同样的事情,但它并没有产生同样的效果(我知道这是我的误解,而不是Go的错误)。
提前感谢:)
答案 0 :(得分:2)
在当前代码中,您有两个类型为Entity
的对象。一个名为e1
,另一个名为database[1]
。这两个对象完全独立,因为它们是struct
。因此,当您更改其中一个时,它不会影响另一个。 (小例外:Items
字段的某些更改将被共享,但不是全部。)
如果您想先将实体添加到地图并稍后进行修改,则应使用指针地图map[int][]*Entity
。然后,您应该使用Entity{}
创建指向实体的指针,而不是e1 := &Entity{}
,然后程序将起作用。对e1.Others
的更改也会影响database[1].Others
,因为这两个变量现在指向同一个对象。
但print
声明会有所不同。它不会打印结构,而只会打印指针值。要解决此问题,请添加String方法:
func (e *Entity) String() string { return fmt.Sprint(*e) }
参见https://play.golang.org/p/edU7E5Gnjw,我还删除了不必要的空切片。附加到nil
切片是完全可以的。
如需进一步阅读,我建议http://research.swtch.com/godata,它将回答您目前的问题。