亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在用作指針的結構中嵌入結構與指向結構的指針

在用作指針的結構中嵌入結構與指向結構的指針

Go
當年話下 2023-07-10 10:49:13
如果我有一個A用作指針的結構類型(僅具有指針接收器,構造函數返回*A等),那么嵌入結構類型與嵌入結構類型有B什么B區別*B?也就是說,有什么區別type B struct {...}type A struct {    B    // ...}和type B struct {...}type A struct {    *B    // ...}例如,是否存在嵌入字段的復制?編輯:我還應該提到嵌入式結構B只有指針接收器。
查看完整描述

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


查看完整回答
反對 回復 2023-07-10
?
滄海一幻覺

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的值不受影響(它仍然是,即使在被分配給之后)structAValstructB542aVal


編輯:

無論如何,如果您structB只有指針接收器,則預期的行為可能是更改structB更新strucA的兩個接收器。這是我的示例中的場景 1,并且肯定需要一個指針。來自圍棋之旅

具有指針接收器的方法可以修改接收器指向的值[...]。由于方法通常需要修改其接收器,因此指針接收器比值接收器更常見。


查看完整回答
反對 回復 2023-07-10
  • 2 回答
  • 0 關注
  • 251 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號