」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > ## 為什麼我不能在 Go 中只複製帶有指標接收器的類型實例?

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

發佈於2024-11-08
瀏覽:113

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

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

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

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

複製指標的問題

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

type Wrapper struct {
    v int
    p *int
}

func (w *Wrapper) Set(v int) {
    w.v = v
    *w.p = v
}

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

範例:

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)

輸出:

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

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

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

最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3