GoLang:在struct中重构xml标记定义

时间:2017-09-18 08:56:16

标签: xml go struct

type Social struct {
    XMLName  xml.Name `xml:"social"`
    Facebook string   `xml:"facebook"`
    Twitter  string   `xml:"twitter"`
    Youtube  string   `xml:"youtube"`
}

在上面的示例中,我在多个结构中重用了xml:"facebook"。我想知道我是否可以将其提取为常量并在所有结构中引用它。

或者你是如何定义我通过规范/文档读取的结构,并没有找到任何具体的方法来实现这一点。

有可能吗?

PS:我的目的是减少重复代码,因为在创建新结构时很容易输入错误(因为它几次发生在我身上)。

2 个答案:

答案 0 :(得分:2)

在您需要的时候重复tag并不是一件令人头疼的事。请注意,在为struct字段定义标记时,规范不允许您使用常量或变量。 struct标记只能是string literal。引自Spec: Struct types:

StructType    = "struct" "{" { FieldDecl ";" } "}" .
FieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .
EmbeddedField = [ "*" ] TypeName .
Tag           = string_lit .

“外包”标签定义的一种方法是将整个结构字段“外包”到另一个结构中,并使Social嵌入该结构。

例如:

type Social struct {
    XMLName xml.Name `xml:"social"`
    HasFacebook
    Twitter string `xml:"twitter"`
    Youtube string `xml:"youtube"`
}

type HasFacebook struct {
    Facebook string `xml:"facebook"`
}

现在您可以在其他类型/结构中重复使用它:

type Social2 struct {
    HasFacebook
    Linkedin string `xml:"linkedin"`
}

测试这两种类型(SocialSocial2):

func main() {
    var s *Social
    if err := xml.Unmarshal([]byte(src), &s); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", s)

    var s2 *Social2
    if err := xml.Unmarshal([]byte(src), &s2); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", s2)
}

const src = `<social>
    <facebook>someface</facebook>
    <twitter>sometwitter</twitter>
    <linkedin>somelinkedin</linkedin>
</social>`

输出(在Go Playground上尝试):

&{XMLName:{Space: Local:social} HasFacebook:{Facebook:someface} Twitter:sometwitter Youtube:}
&{HasFacebook:{Facebook:someface} Linkedin:somelinkedin}

答案 1 :(得分:1)

  

有可能吗?

没有。这是不可能的。