複製實例時指針接收器的重要性
操作資料時,請理解按引用或按值傳遞值的細微差別至關重要。在 Go 中,方法可以使用值接收器或指標接收器來定義,理解這種選擇的含義至關重要,尤其是在複製實例時。
值接收器
具有值接收器的方法對它們接收到的值的副本進行操作。方法內所做的任何修改都不會影響原始值。這確保了在複製的實例上呼叫方法不會損害原始資料。
指標接收器
相反,具有指標接收器的方法允許直接存取和修改原始值。此類方法有可能改變數據,從而導致微妙且意想不到的副作用。使用指標接收器複製實例存在在原始資料和複製資料之間引入不一致的風險。
範例:Wrapper Struct
為了說明該問題,請考慮一種稱為Wrapper 的型別包含欄位v(值)和p(指向值的指標) :
type Wrapper struct {
v int
p *int
}
有指標接收器的 Set() 方法同時修改 v 和所指向的值:
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
假設我們有一個Wrapper 實例a:
a := Wrapper{v: 0, p: new(int)}
呼叫Set() on a 將同時修改v 和*p:
a.Set(1)
a.Set(1)b := a
b := afmt.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)
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
a.設定(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.v=0, a.p=0; b.v=0, b.p=0 a.v=1,a.p=1; b.v=0, b.p=1
結論
處理具有指標接收器方法的類型時,避免複製實例以防止資料不一致至關重要。相反,對指標值進行操作以確保修改反映在引用相同基礎資料的所有實例中。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3