我正在尝试了解go中的嵌套结构,所以我做了一个小测试:(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
}
那么最后两行的工作方式和原因是什么?它们是一样的吗?我应该使用哪种?
答案 0 :(得分:4)
他们是一样的。见the Go Spec on selectors:
对于类型
x
或T
的值*T
,T
不是指针或接口类型,x.f
表示字段或方法T
中最浅的深度,其中有f
。如果没有一个f
具有最浅的深度,则选择器表达式是非法的。
请注意,如果类型b.a
在同一深度上嵌入了两个具有相同字段的类型,则表示B
是非法的:
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