我想創(chuàng)建一個(gè)可以在其他包中訪問(wèn)的結(jié)構(gòu),但我不想允許修改這個(gè)結(jié)構(gòu)。在其他語(yǔ)言中,這是通過(guò)將所有字段設(shè)為私有并僅公開(kāi)公共吸氣劑來(lái)存檔的。使用 getter 的解決方案適用于除切片和映射之外的所有數(shù)據(jù)類型,因?yàn)槟J(rèn)情況下不會(huì)復(fù)制返回的切片和映射,因此可以修改它們。我想出的唯一解決方案是創(chuàng)建新的地圖/切片并在循環(huán)中分配所有項(xiàng)目,但這會(huì)引入大量重復(fù)且丑陋的代碼,尤其是對(duì)于大型嵌套結(jié)構(gòu)。package mainimport ( "fmt")type OtherStruct struct { prop string}type Struct struct { prop map[string]OtherStruct}func (s Struct) Prop() map[string]OtherStruct { return s.prop}func (s Struct) Prop2() map[string]*OtherStruct { prop := make(map[string]*OtherStruct, 0) for k := range s.prop { v := s.prop[k] prop[k] = &v } return prop}func main() { var s Struct; // Simple getter s = Struct{make(map[string]OtherStruct, 0)} p1 := s.Prop() fmt.Println(s) // &{map[]} p1["something"] = OtherStruct{"test"} fmt.Println(s) // {map[something:{test}]} // Getter which copies map s = Struct{make(map[string]OtherStruct, 0)} p2 := s.Prop2() fmt.Println(s) // &{map[]} p2["something"] = &OtherStruct{"test"} fmt.Println(s) // &{map[]}}有沒(méi)有更好的方法在 Go 中封裝切片/映射?或者我根本不應(yīng)該在 Go 中使用封裝并使用不同的方法?
1 回答

慕田峪4524236
TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超5個(gè)贊
返回切片或映射值是慣用的 Go。你的包的用戶將知道這些數(shù)據(jù)結(jié)構(gòu)在 Go 中是如何工作的。
在您的示例中, 的用戶Struct應(yīng)該知道在返回的地圖中添加新條目將反映同一地圖的任何其他用戶。
// Simple getter
s = Struct{make(map[string]OtherStruct, 0)}
p1 := s.Prop()
fmt.Println(s) // &{map[]}
p1["something"] = OtherStruct{"test"}
fmt.Println(s) // {map[something:{test}]}
只有在并發(fā)的情況下你才應(yīng)該擔(dān)心這些事情。也就是說(shuō),當(dāng)多個(gè) goroutine 正在訪問(wèn)并可能更改切片或映射中的元素時(shí)。
- 1 回答
- 0 關(guān)注
- 128 瀏覽
添加回答
舉報(bào)
0/150
提交
取消