嵌入式结构反对情况

时间:2017-07-10 17:24:51

标签: go

我们有3种类型:

type A struct {
    B
    C
}
type B struct {
    x int
    y string
}
type C struct {
    z string
}

由于匿名字段的字段和方法是promoted,我们可以访问B中的匿名字段A的字段

var a A
a.x = 0

非常明显的是B& C嵌入A,因此我们希望A等同于:

type D struct {
    x int
    y string
    z string
}

您期望看到什么?

我们希望我们可以编写A类型的复合文字:

a := A{x: 2}

你看到了什么?

此编译错误:

unknown field 'x' in struct literal of type A

我们的问题

为什么不能以这种方式为A编写复合文字,就像D类型一样?

https://play.golang.org/p/uM5JkO5EvE

2 个答案:

答案 0 :(得分:2)

Rob' Commander'派克解释说here

他在那里写道:

  

可能有一天,但因为它需要提供更多   信息对数据类型的变化更加健壮。

如果我理解并正确理解,它基本上是一种安全措施。如果结构定义与复合文​​字不匹配,编译器会对你大喊。

在您的示例中,A的定义可能会发生变化 - 在稍后的更改中(如在更晚的时候,如年) - :

    type A struct {
        x int
        y string
        z string
    }

稍后,但xyz可能代表与以前不同的事情,因此您必须将所有文字更改为 没有得到某种腐败的数据。

这是一个慎重的选择。语言规范中的措辞是:

  

提升字段的作用类似于结构的普通字段,除了它们不能用作结构的复合文字中的字段名称。

因此,您可以使用字段x的字段B,就好像它是A的字段,除了复合文字。

和类型

type A struct {
    B
    C
}

type A struct {
    x int
    y string
    z string
}

真的是两件不同的事情。前者包含两个字段BC,后三个字段xyz。前者只需要一些语法糖就可以用速记来访问字段x的字段B。因此,如果a是前一种类型A的变量,则a.xa.B.x的语法糖。

答案 1 :(得分:1)

初始化B时,您需要明确使用C(和A):

a = A{B{x: 2}, C{}}