2 回答

TA貢獻1821條經驗 獲得超5個贊
兩種結構的零值不同,這可能是一個顯著的人體工程學差異。
考慮嵌入類型
type B struct {
X int
}
func (b *B) Print() { fmt.Printf("%d\n", b.X) }
如果我們直接將其嵌入為對象
type AObj struct {
B
}
那么 type 的零值AObj包括類型 的嵌入對象B,該對象也有其零值,因此我們可以安全地
var aObj AObj
aObj.Print() // prints 0
但如果我們嵌入一個指針
type APtr struct {
*B
}
這個結構體的零值有一個 nil 指針值,我們不能真正直接使用它。
var aPtr APtr
aPtr.Print() // panics
對象有望以您期望的方式被復制。如果您創建一個新AObj對象,它將獲得嵌入的B.
aObj2 := aObj
aObj.X = 1
aObj2.Print() // prints 0, because it has a copy
如果創建一個新APtr對象,它會獲得 的副本*B,這意味著它共享底層的具體對象。
aPtr.B = &B{}
aPtr2 := aPtr
aPtr.X = 1
aPtr2.Print() // prints 1, because both objects point at the same B
可運行示例位于https://play.golang.org/p/XmOgegwVFeE

TA貢獻1824條經驗 獲得超5個贊
考慮一個簡單的示例程序。AstructAPtr嵌入一個指針,a直接structAVal嵌入一個結構體:structB
package main
import "fmt"
type structB struct {
foo int
}
type structAPtr struct {
bar *structB
}
type structAVal struct {
bar structB
}
func main() {
// referencing bStruct
b1 := structB{foo: 12}
aPtr := structAPtr{bar: &b1}
fmt.Println("Before assignment:")
fmt.Printf("aPtr.bar.foo = %d, b.foo = %d\n", aPtr.bar.foo, b1.foo)
aPtr.bar.foo = 42
fmt.Println("After assignment:")
fmt.Printf("aPtr.bar.foo = %d, b.foo = %d\n", aPtr.bar.foo, b1.foo)
// copying bStruct
b2 := structB{foo: 12}
aVal := structAVal{bar: b2}
fmt.Println("Before assignment:")
fmt.Printf("aVal.bar.foo = %d, b.foo = %d\n", aVal.bar.foo, b2.foo)
aVal.bar.foo = 42
fmt.Println("After assignment:")
fmt.Printf("aVal.bar.foo = %d, b.foo = %d\n", aVal.bar.foo, b2.foo)
}
intstructB.foo用于演示在orstructB內部進行操作時是否會發生變化。structAPtrstructAVal
該程序輸出:
Before assignment:
aPtr.bar.foo = 12, b.foo = 12
After assignment:
aPtr.bar.foo = 42, b.foo = 42 <------------ both changed
Before assignment:
aVal.bar.foo = 12, b.foo = 12
After assignment:
aVal.bar.foo = 42, b.foo = 12 <------------ only assignee changed
查看結果顯示:
改變指針的值來
structB
改變structB
更改復制版本
structB
的值不受影響(它仍然是,即使在被分配給之后)structAVal
structB
5
42
aVal
編輯:
無論如何,如果您structB
只有指針接收器,則預期的行為可能是更改structB
更新strucA
的兩個接收器。這是我的示例中的場景 1,并且肯定需要一個指針。來自圍棋之旅:
具有指針接收器的方法可以修改接收器指向的值[...]。由于方法通常需要修改其接收器,因此指針接收器比值接收器更常見。
- 2 回答
- 0 關注
- 251 瀏覽
添加回答
舉報