我对 Go 关于嵌入式结构中变量“覆盖”的行为有点困惑。
第一种情况
如果一个child结构嵌入了一个parent包含字段的结构,我可以使用orAttr访问 Attr 的值。这是一个例子:child.Attrchild.parent.Attr
package main
import (
"fmt"
"encoding/json"
)
type parent struct {
Attr int `json:"attr"`
}
type child struct {
parent
}
func main() {
var c child
json.Unmarshal([]byte(`{"i": 1}`), &c)
fmt.Println(c.Attr)
fmt.Println(c.parent.Attr)
}
Run Code Online (Sandbox Code Playgroud)
第二种情况
但是,如果子结构本身包含一个名为 的字段Attr,则这两个字段是不同的,可以单独访问,如下例所示:
package main
import (
"fmt"
"encoding/json"
)
type parent struct {
Attr int `json:"attr"`
}
type child struct {
parent
Attr int
}
func main() {
var c child
json.Unmarshal([]byte(`{"attr": 1}`), &c)
fmt.Println(c.Attr)
fmt.Println(c.parent.Attr)
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶 golang 中允许这种隐式行为。我本以为语言会更加严格,因为它在很多方面都如此。此外,我找不到关于此的明确规范。这只是一个副作用还是我可以使用该功能?
Golang 规范实际上规定了如何解析嵌入字段
选择器 f 可以表示类型 T 的字段或方法 f,也可以指 T 的嵌套嵌入字段的字段或方法 f。遍历到达 f 的嵌入字段的数量称为它在 T 中的深度。 T 中声明的字段或方法 f 的深度为零。T 中嵌入字段 A 中声明的字段或方法 f 的深度是 A 中 f 的深度加一。
然后...
对于 T 或 *T 类型的值 x(其中 T 不是指针或接口类型),xf 表示 T 中最浅深度处存在 f 的字段或方法。如果不存在恰好一个深度最浅的 f,则选择器表达式是非法的。