If I have a struct type A
which is used as a pointer (has pointer receivers only, the constructor returns *A
, etc.), what is the difference between embedding a struct type B
as B
versus *B
?
That is, what is the difference between
type B struct {...}
type A struct {
B
// ...
}
and
type B struct {...}
type A struct {
*B
// ...
}
For example, is there ever copying of the embedded field?
Edit: I should also mention that the embedded struct B
only has pointer receivers.
The zero values of the two structures are different, which can be a significant ergonomic difference.
Consider an embedded type
type B struct {
X int
}
func (b *B) Print() { fmt.Printf("%d\n", b.X) }
If we embed this directly as an object
type AObj struct {
B
}
then the zero value of type AObj
includes an embedded object of type B
, which also has its zero value, and therefore we can safely
var aObj AObj
aObj.Print() // prints 0
But if we instead embed a pointer
type APtr struct {
*B
}
the zero value of this struct has a nil pointer value, and we can't really use it directly.
var aPtr APtr
aPtr.Print() // panics
Objects get copied in hopefully the way you might expect. If you create a new AObj
object, it gets a copy of the embedded B
.
aObj2 := aObj
aObj.X = 1
aObj2.Print() // prints 0, because it has a copy
If you create a new APtr
object, it gets a copy of the *B
, which means it shares the underlying concrete object.
aPtr.B = &B{}
aPtr2 := aPtr
aPtr.X = 1
aPtr2.Print() // prints 1, because both objects point at the same B
Runnable example at https://play.golang.org/p/XmOgegwVFeE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With