【问题标题】:Directly vs indirectly nested structs直接与间接嵌套结构
【发布时间】:2017-02-27 15:30:05
【问题描述】:

在 Go documentation for xml:Unmarshal 中有一个解组此 xml 的示例

    <Person>
        <FullName>Grace R. Emlin</FullName>
        <Company>Example Inc.</Company>
        <Email where="home">
            <Addr>gre@example.com</Addr>
        </Email>
        <Email where='work'>
            <Addr>gre@work.com</Addr>
        </Email>
        <Group>
            <Value>Friends</Value>
            <Value>Squash</Value>
        </Group>
        <City>Hanga Roa</City>
        <State>Easter Island</State>
    </Person>

使用这些结构

    type Address struct {
        City, State string
    }
    type Result struct {
        XMLName xml.Name `xml:"Person"`
        Name    string   `xml:"FullName"`
        Phone   string
        Email   []Email
        Groups  []string `xml:"Group>Value"`
        Address
    }

注意Result 包含对单独定义的Address 的引用。显然,这段代码有效。


当我尝试解组此 xml 时

<C>
  <D>
    <E>Fred</E>
    <F>42</F>
  </D>
</C>

使用这些结构

type D struct { 
  E string
  F int
}
type C struct {   // Compiles OK but result empty.
  D 
} 

我得到空结果{{ 0}}。但是下面的结构可以正常工作产生{{Fred 42}}

type C struct {   // This works.
  D struct { 
    E string
    F int
  }
}

Playground example

我是否遗漏了一些关于结构的微妙之处?

【问题讨论】:

    标签: xml go struct nested


    【解决方案1】:

    当你这样做时:

    type C struct {
        D
    }
    

    这称为embeddingD 是一个匿名字段或嵌入字段)。您可能会认为这就像嵌入类型的字段(和方法)成为嵌入类型的一部分(它们得到提升)。所以在这种情况下,写C.EC.F 是“合法的”。

    当你这样做时:

    type C struct {
        D struct {
          E string
          F int
        }
    }
    

    不是嵌入(或“嵌套”)。这里DC 类型的“常规”、命名 字段。 D 是字段的名称,后面是匿名的type literal,即字段的类型。这里写C.EC.F是不合法的,只能写C.D.EC.D.F。这是您尝试解组的 XML 结构的正确映射,因此可以正常工作(在 Go Playground 上尝试)。

    请注意,如果您将嵌入更改为常规字段,它也可以工作(在Go Playground 上尝试):

    type C struct {
        D D
    }
    

    另外请注意,如果您在字段标签中指定 XML 元素路径,则可以跳过整个 D 包装器结构:

    type C struct {
        E string `xml:"D>E"`
        F int    `xml:"D>F"`
    }
    

    Go Playground 上试试。

    【讨论】:

      猜你喜欢
      • 2013-11-23
      • 2021-12-24
      • 2013-05-10
      • 2019-08-14
      • 1970-01-01
      • 2023-03-04
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多