2017-02-27 152 views
5

在轉到documentation for xml:Unmarshal有,使用這些結構直接VS間接嵌套結構

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

<Person> 
     <FullName>Grace R. Emlin</FullName> 
     <Company>Example Inc.</Company> 
     <Email where="home"> 
      <Addr>[email protected]</Addr> 
     </Email> 
     <Email where='work'> 
      <Addr>[email protected]</Addr> 
     </Email> 
     <Group> 
      <Value>Friends</Value> 
      <Value>Squash</Value> 
     </Group> 
     <City>Hanga Roa</City> 
     <State>Easter Island</State> 
    </Person> 

一個例子。很明顯,這段代碼有效。


當我嘗試使用這些結構

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

解組此XML

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

我得到空的結果{{ 0}}。但是下面的結構工程確定生產{{Fred 42}}

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

Playground example

我是否錯過了關於結構的一些微妙點?

回答

5

當你這樣做:

type C struct { 
    D 
} 

這就是所謂的embeddingD是嵌入式領域的匿名場或)。你可能會想到,就好像嵌入類型的字段(和方法)成爲嵌入類型的一部分(他們得到升級)。所以在這種情況下,編寫C.EC.F是「合法的」。

當你這樣做:

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

這是嵌入(或 「嵌套」)。這裏的D是一個「正規」,的名稱爲字段的C類型。 D是該字段的名稱,後跟匿名type literal,該字段的類型。這裏寫C.EC.F,只有C.D.EC.D.F是不合法的。這是您嘗試解組的XML結構的正確映射,因此這可以工作(在Go Playground上嘗試)。

請注意,如果你改變了嵌入到正規的領域,它也將工作(嘗試在Go Playground):

type C struct { 
    D D 
} 

另外請注意,你可以跳過整個D包裝結構,如果你指定在該領域的標籤XML元素路徑:

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

嘗試它的Go Playground