如果我有一个用作指针的结构类型A
(仅具有指针接收器,则构造函数返回*A
等),嵌入结构类型{{ 1}}是B
与B
相对?
也就是说,两者之间有什么区别
*B
和
type B struct {...}
type A struct {
B
// ...
}
例如,是否曾经复制过嵌入字段?
编辑:我还应该提到嵌入式结构type B struct {...}
type A struct {
*B
// ...
}
仅具有指针接收器。
答案 0 :(得分:2)
两个结构的零值不同,这可能是人体工程学上的显着差异。
考虑嵌入式类型
type B struct {
X int
}
func (b *B) Print() { fmt.Printf("%d\n", b.X) }
如果我们直接将其作为对象嵌入
type AObj struct {
B
}
然后,类型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
答案 1 :(得分:1)
考虑一个简单的示例程序。 structAPtr
嵌入指针,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)
}
int structB.foo
用于演示structB
在structAPtr
或structAVal
内部进行操作时是否发生了变化。
该程序输出:
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
查看结果显示:
将 pointer 的值更改为structB
会更改structB
在structB
中更改复制版本structAVal
的值使structB
不受影响(即使分配了5
之后,它仍然42
到aVal
)
编辑:
如果您的structB
仅具有指针接收器,则预期的行为可能是更改structB
中的strucA
会同时更新它们。在我的示例中,这是场景1,肯定需要一个指针。来自围棋之旅:
带有指针接收器的方法可以修改接收器指向的值。由于方法通常需要修改其接收者,因此指针接收者比值接收者更为普遍。
希望有帮助!