首頁  >  文章  >  後端開發  >  ## 為什麼我不能在 Go 中只複製帶有指標接收器的類型實例?

## 為什麼我不能在 Go 中只複製帶有指標接收器的類型實例?

Linda Hamilton
Linda Hamilton原創
2024-10-25 05:03:02171瀏覽

## Why Can't I Just Copy Instances of Types With Pointer Receivers in Go?

了解指標接收器和複製實例

在 Go 中,可以使用值接收器或指標接收器來定義方法。當類型 T 的所有方法都具有 T 本身的接收者類型時,複製該類型的實例是安全的,因為呼叫其任何方法都必然會進行複製。

但是,當類型有帶有指標接收器的方法時。在這種情況下,應避免複製該類型的實例,因為它可能違反內部不變量。

複製指標的問題

讓我們考慮一個範例來說明問題。假設我們有一個有兩個欄位的類型 Wrapper:值 v 和指標 p。我們打算在 v 和 p 的指向值中儲存相同的數字。為了確保這一點,我們提供了一個帶有指標接收器的 Set 方法:

<code class="go">type Wrapper struct {
    v int
    p *int
}

func (w *Wrapper) Set(v int) {
    w.v = v
    *w.p = v
}</code>

如果我們有一個 Wrapper 實例並呼叫 Set 方法,它將修改 p 的指向值。但是,如果我們建立實例的副本,則副本將與原始實例共用相同的指標值 p。這意味著對任一實例的任何後續方法呼叫都會影響兩個副本。

範例:

<code class="go">a := Wrapper{v: 0, p: new(int)}
b := a

fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)

a.Set(1)
fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)</code>

輸出:

a.v=0, a.p=0;  b.v=0, b.p=0
a.v=1, a.p=1;  b.v=0, b.p=1

In本例中,呼叫a.Set(1) 後,b 的值變成無效,因為b.v 不等於*b.p。這是因為 a 和 b 中的指標 p 都指向相同的基礎值。

為了避免此類問題,建議在使用帶有指標接收器的方法時使用指標值。或者,如果該類型只能具有值接收器,則無論方法呼叫如何,複製該類型的實例都是安全的。

以上是## 為什麼我不能在 Go 中只複製帶有指標接收器的類型實例?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn