2016-08-18 48 views
3

我想了解如何操作Go中的數據結構,以及其指針(與副本或引用)的方法。golang追加到一個片內結構

我的代碼是在圍棋遊樂場,在這裏: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{}上嘗試過,但它沒有產生同樣的效果(我知道這是我的誤解,不是Go的錯)。

在此先感謝:)

回答

2

在你現在的代碼,你有Entity類型的兩個對象。一個被命名爲e1,另一個被命名爲database[1]。這兩個對象是完全獨立的,因爲它們是struct s。因此,當你改變其中一個時,它不會影響另一個。 (小例外:Items字段的一些更改將被共享,但不是全部。)

如果要首先將實體添加到地圖並稍後修改它,則應使用指針的地圖map[int][]*Entity。然後,而不是Entity{},你應該創建一個指向一個實體的指針,e1 := &Entity{},然後該程序將工作。 e1.Others的更改也會影響database[1].Others,因爲這兩個變量現在指向相同的對象。

print聲明將有所不同。而不是打印結構,它只會打印一個指針值。爲了解決這個問題,添加一個字符串方法:

func (e *Entity) String() string { return fmt.Sprint(*e) } 

https://play.golang.org/p/edU7E5Gnjw,在這裏我也去掉了不必要的空片。完全可以追加到nil切片。

爲了進一步閱讀,我建議http://research.swtch.com/godata,這將回答你目前的問題。

+0

非常感謝你!你添加的鏈接也很有幫助:D – weeanon