首頁 > 後端開發 > Golang > 為什麼帶有指標接收器的 Go 方法會修改非指標參數?

為什麼帶有指標接收器的 Go 方法會修改非指標參數?

Barbara Streisand
發布: 2024-12-05 11:35:11
原創
488 人瀏覽過

Why Does a Go Method with a Pointer Receiver Modify a Non-Pointer Argument?

為什麼帶有指標接收器的方法在接收非指標時仍然會改變值?

在 Go 中,帶有指標接收器的方法會保留其操作的變數的原始值在。然而,當一個方法需要一個指標參數並傳遞一個非指標值時,似乎存在明顯的矛盾。

考慮Go 之旅中練習51 的以下程式碼片段:

func (v *Vertex) Scale(f float64) {
    v.X *= f
    v.Y *= f
}

func main() {
    v := &Vertex{3, 4}
    v.Scale(2)
    fmt.Println(v) // Output: &{6 8}
}
登入後複製

根據解釋,Scale方法不應該修改v,因為它接收的是指向Vertex(*Vertex)的指針而不是Vertex

但是,當我們將main 中的v := &Vertex{3, 4} 行改為 v := Vertex{3, 4} 時,輸出從 &{6 8} 改為 {6 8 (注意缺少 &)。這表示 v 已被修改,即使它作為非指標值傳遞。

解釋

關鍵在於 Go 的強型別性質與編譯器最佳化。即使 Scale 方法需要一個指標接收器,它仍然可以接受非指標值,因為 Go 會隱含地將它們轉換為指標。

具體來說,編譯器重寫以下程式碼:

v := Vertex{3, 4}
v.Scale(2)
登入後複製

to:

(&v).Scale(2)
登入後複製

這表示該方法實際上是用指向v 的指針呼叫的,這允許它修改原始的

以下特定於Go的規則解釋了此行為:

如果 x(的類型)的方法集包含 m 並且參數列表可以,則方法調用 x.m() 是有效的被分配給m的參數列表。如果 x 是可尋址的,且 &x 的方法集包含 m,則 x.m() 是 (&x).m() 的簡寫。

綜上所述,具有指標接收器的方法仍然可以修改非指標變量,因為編譯器會自動轉換它們指向指標以保持方法類型安全。

以上是為什麼帶有指標接收器的 Go 方法會修改非指標參數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板