嵌入指向結構體的指針與嵌入結構體本身
在給定的場景中,結構體類型A 用作結構體類型指標並且僅包含指標接收器,將結構類型B 嵌入為B 與*B 之間存在差異。
零值行為
最明顯的差異在於所得結構的零值。當按原樣嵌入 B 時,類型 A 的零值將包含類型 B 的嵌入對象,該對像也保留其零值。這使得無需事先初始化即可無縫使用嵌入欄位:
type B struct { X int } func (b *B) Print() { fmt.Printf("%d\n", b.X) } type AObj struct { B } var aObj AObj aObj.Print() // prints 0
另一方面,嵌入*B 會導致帶有nil 指標的零值,從而阻止直接欄位存取:
type APtr struct { *B } var aPtr APtr aPtr.Print() // panics
欄位複製
建立A 類型的新物件時,欄位複製的行為與直覺一致。嵌入 B 直接在新物件中建立嵌入物件的副本,保留獨立性:
aObj2 := aObj aObj.X = 1 aObj2.Print() // prints 0, due to a separate instance of B
相反,嵌入 *B 建立指標的副本而不是底層具體物件。這意味著兩個物件共享相同的B 實例,從而影響字段修改:
aPtr.B = &B{} aPtr2 := aPtr aPtr.X = 1 aPtr2.Print() // prints 1, as both objects point to the same B
本質上,嵌入B 創建所包含結構的不同實例,而嵌入*B 在多個嵌入結構中共享單一具體實例。這種差異會影響零值語義和欄位複製的行為。
以上是在 Go 中何時嵌入指向結構體的指標與結構體本身?的詳細內容。更多資訊請關注PHP中文網其他相關文章!