在用作指针的结构中嵌入结构与指向结构的指针

如果我有一个A用作指针的结构类型(仅具有指针接收器,构造函数返回*A等),那么嵌入结构类型与嵌入结构类型有B什么B区别*B?


也就是说,有什么区别


type B struct {...}

type A struct {

    B

    // ...

}


type B struct {...}

type A struct {

    *B

    // ...

}

例如,是否存在嵌入字段的复制?


编辑:我还应该提到嵌入式结构B只有指针接收器。


当年话下
浏览 209回答 2
2回答

收到一只叮咚

两种结构的零值不同,这可能是一个显着的人体工程学差异。考虑嵌入类型type B struct {    X int}func (b *B) Print() { fmt.Printf("%d\n", b.X) }如果我们直接将其嵌入为对象type AObj struct {    B}那么 type 的零值AObj包括类型 的嵌入对象B,该对象也有其零值,因此我们可以安全地var aObj AObjaObj.Print() // prints 0但如果我们嵌入一个指针type APtr struct {    *B}这个结构体的零值有一个 nil 指针值,我们不能真正直接使用它。var aPtr APtraPtr.Print() // panics对象有望以您期望的方式被复制。如果您创建一个新AObj对象,它将获得嵌入的B.aObj2 := aObjaObj.X = 1aObj2.Print() // prints 0, because it has a copy如果创建一个新APtr对象,它会获得 的副本*B,这意味着它共享底层的具体对象。aPtr.B = &B{}aPtr2 := aPtraPtr.X = 1aPtr2.Print() // prints 1, because both objects point at the same B可运行示例位于https://play.golang.org/p/XmOgegwVFeE

沧海一幻觉

考虑一个简单的示例程序。AstructAPtr嵌入一个指针,a直接structAVal嵌入一个结构体:structBpackage mainimport "fmt"type structB struct {&nbsp; &nbsp; foo int}type structAPtr struct {&nbsp; &nbsp; bar *structB}type structAVal struct {&nbsp; &nbsp; bar structB}func main() {&nbsp; &nbsp; // referencing bStruct&nbsp; &nbsp; b1 := structB{foo: 12}&nbsp; &nbsp; aPtr := structAPtr{bar: &b1}&nbsp; &nbsp; fmt.Println("Before assignment:")&nbsp; &nbsp; fmt.Printf("aPtr.bar.foo = %d, b.foo = %d\n", aPtr.bar.foo, b1.foo)&nbsp; &nbsp; aPtr.bar.foo = 42&nbsp; &nbsp; fmt.Println("After assignment:")&nbsp; &nbsp; fmt.Printf("aPtr.bar.foo = %d, b.foo = %d\n", aPtr.bar.foo, b1.foo)&nbsp; &nbsp; // copying bStruct&nbsp; &nbsp; b2 := structB{foo: 12}&nbsp; &nbsp; aVal := structAVal{bar: b2}&nbsp; &nbsp; fmt.Println("Before assignment:")&nbsp; &nbsp; fmt.Printf("aVal.bar.foo = %d, b.foo = %d\n", aVal.bar.foo, b2.foo)&nbsp; &nbsp; aVal.bar.foo = 42&nbsp; &nbsp; fmt.Println("After assignment:")&nbsp; &nbsp; 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 = 12After assignment:aPtr.bar.foo = 42, b.foo = 42 <------------ both changedBefore assignment:aVal.bar.foo = 12, b.foo = 12After assignment:aVal.bar.foo = 42, b.foo = 12 <------------ only assignee changed查看结果显示:改变指针的值来structB改变structB更改复制版本structB的值不受影响(它仍然是,即使在被分配给之后)structAValstructB542aVal编辑:无论如何,如果您structB只有指针接收器,则预期的行为可能是更改structB更新strucA的两个接收器。这是我的示例中的场景 1,并且肯定需要一个指针。来自围棋之旅:具有指针接收器的方法可以修改接收器指向的值[...]。由于方法通常需要修改其接收器,因此指针接收器比值接收器更常见。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go