Golang 嵌入式结构

Nic*_*ier 1 go

我对 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 中允许这种隐式行为。我本以为语言会更加严格,因为它在很多方面都如此。此外,我找不到关于此的明确规范。这只是一个副作用还是我可以使用该功能?

Giu*_*oni 5

Golang 规范实际上规定了如何解析嵌入字段

选择器 f 可以表示类型 T 的字段或方法 f,也可以指 T 的嵌套嵌入字段的字段或方法 f。遍历到达 f 的嵌入字段的数量称为它在 T 中的深度。 T 中声明的字段或方法 f 的深度为零。T 中嵌入字段 A 中声明的字段或方法 f 的深度是 A 中 f 的深度加一。

然后...

对于 T 或 *T 类型的值 x(其中 T 不是指针或接口类型),xf 表示 T 中最浅深度处存在 f 的字段或方法。如果不存在恰好一个深度最浅的 f,则选择器表达式是非法的。