亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

前進:使用指針可以更改結構的內容。為什么?

前進:使用指針可以更改結構的內容。為什么?

Go
DIEA 2021-05-07 14:53:34
考慮以下示例。我不完全了解“后臺”會發生什么,并尋求解釋。從主函數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).EntryptrFoo.EntryGo中的相同。

因此,這里的問題是,對于那些不習慣的人,語法隱藏了一些正在發生的事情。在C語言中,除非傳遞了指向結構的指針,否則您將永遠無法編輯該結構。Go中也會發生同樣的情況。您需要使用指針接收器才能修改接收的內容。


查看完整回答
反對 回復 2021-05-17
?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

如何確定不復制該結構?是否有可能對此進行編譯時/運行時檢查,或者我要小心嗎?

簡短的答案是,,您不能為此進行編譯時或運行時(1)檢查-您只需要小心。一旦您對go有了一些熟悉,這便成為自然。

(1) 從技術上講,您的函數可以使用類型開關查詢類型是否為指針,但是如果您記得這樣做,則還記得將參數設置為指針。


查看完整回答
反對 回復 2021-05-17
?
交互式愛情

TA貢獻1712條經驗 獲得超3個贊

查看完整回答
反對 回復 2021-05-17
  • 2 回答
  • 0 關注
  • 280 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號