考慮以下示例。我不完全了解“后臺”會發生什么,并尋求解釋。從主函數Foo調用時,此版本似乎復制了該結構AddToEntry。正確的?如何在代碼中“證明”這一點?當go復制該結構時,我只是在操縱該結構的副本,當我返回該main函數時,是否像以前一樣看到原始文件?當我希望有一個指針(請參見代碼中的注釋)時,一切都很好,沒有復制我的結構。如何避免這種“錯誤”?如何確定不復制該結構?是否有可能對此進行編譯時/運行時檢查,或者我要小心嗎?package mainimport ( "fmt")type Foo struct { Entry []string}func MakeFoo() Foo { a:=Foo{} a.Entry = append(a.Entry,"first") return a}// if I change (f Foo) to (f *Foo), I get // the "desired" resultfunc (f Foo) AddToEntry() { f.Entry = append(f.Entry,"second")}func main() { f:=MakeFoo() fmt.Println(f) // {[first]} f.AddToEntry() fmt.Println(f) // {[first]}}
2 回答

青春有我
TA貢獻1784條經驗 獲得超8個贊
您的方法簽名為func (f Foo) AddToEntry()
。方法的工作方式與以下方式f.AddToEntry()
相同:
g := Foo.AddToEntry g(f)
接收器只是另一個參數。為什么這很重要?當您傳遞結構并在函數中對其進行修改時會發生什么?在C,Go和其他按值傳遞語言中,參數中給出的結構僅是副本。因此,您不能修改原始文件。只返回新的結構。
定義時func (f *Foo) AddToEntry()
,您正在將接收器(第一個參數)定義為指針。顯然,給定一個指針,您可以修改原始結構。隱藏的是您在Go中訪問結構時隱式引用。換句話說,(*ptrFoo).Entry
與ptrFoo.Entry
Go中的相同。
因此,這里的問題是,對于那些不習慣的人,語法隱藏了一些正在發生的事情。在C語言中,除非傳遞了指向結構的指針,否則您將永遠無法編輯該結構。Go中也會發生同樣的情況。您需要使用指針接收器才能修改接收的內容。
- 2 回答
- 0 關注
- 280 瀏覽
添加回答
舉報
0/150
提交
取消