Reputation: 41570
I'm trying to understand nested structs in go, so I made a little test: (playground)
type A struct {
a string
}
type B struct {
A
b string
}
func main() {
b := B{A{"a val"}, "b val"}
fmt.Printf("%T -> %v\n", b, b) // B has a nested A and some values
// main.B -> {{a val} b val}
fmt.Println("b.b ->", b.b) // B's own value
// b.b -> b val
fmt.Println("b.A.a ->", b.A.a) // B's nested value
// b.a -> a val
fmt.Println("b.a ->", b.a) // B's nested value? or own value?
// b.a -> a val
}
So how and why the last two lines work? Are they are same? Which should I use?
Upvotes: 3
Views: 1089
Reputation: 36189
They are the same. See the Go Spec on selectors:
For a value
x
of typeT
or*T
whereT
is not a pointer or interface type,x.f
denotes the field or method at the shallowest depth inT
where there is such anf
. If there is not exactly onef
with shallowest depth, the selector expression is illegal.
Note that this means that b.a
is illegal if type B
embeds two types with the same field on the same depth:
type A1 struct{ a string }
type A2 struct{ a string }
type B struct {
A1
A2
}
// ...
b := B{A1{"a1"}, A2{"a2"}}
fmt.Println(b.a) // Error: ambiguous selector b.a
Playground: http://play.golang.org/p/PTqm-HzBDr.
Upvotes: 5