2 回答

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

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超5個(gè)贊
考慮一個(gè)簡(jiǎn)單的示例程序。AstructAPtr嵌入一個(gè)指針,a直接structAVal嵌入一個(gè)結(jié)構(gòu)體: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內(nèi)部進(jìn)行操作時(shí)是否會(huì)發(fā)生變化。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
查看結(jié)果顯示:
改變指針的值來(lái)
structB
改變structB
更改復(fù)制版本
structB
的值不受影響(它仍然是,即使在被分配給之后)structAVal
structB
5
42
aVal
編輯:
無(wú)論如何,如果您structB
只有指針接收器,則預(yù)期的行為可能是更改structB
更新strucA
的兩個(gè)接收器。這是我的示例中的場(chǎng)景 1,并且肯定需要一個(gè)指針。來(lái)自圍棋之旅:
具有指針接收器的方法可以修改接收器指向的值[...]。由于方法通常需要修改其接收器,因此指針接收器比值接收器更常見(jiàn)。
- 2 回答
- 0 關(guān)注
- 266 瀏覽
添加回答
舉報(bào)