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

In the above example I have the xml:"facebook" reused in multiple structs. I would like to know if I can extract it to a constant and reference it in all structs.

Or is that how you have to define the struct I read through the specs/documentations and did not find any specific way to achieve this.

Is it possible?

PS: My intention was to reduce the duplicate code as it is easy to mistype when you create a new struct (as it had happened to me few times).

2 Answers 2

2

It's not a headache to repeat a tag whenever you need it. Note that the spec does not allow you to use constants or variables when defining tags for struct fields. The struct tag can only be a string literal. Quoting from Spec: Struct types:

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

One way to "outsource" the tag definition would be to "outsource" the whole struct field into another struct, and have Social embed that struct.

For example:

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

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

And now you can reuse it in other types / structs:

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

Testing both types (Social and Social2):

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>`

Output (try it on the Go Playground):

&{XMLName:{Space: Local:social} HasFacebook:{Facebook:someface} Twitter:sometwitter Youtube:}
&{HasFacebook:{Facebook:someface} Linkedin:somelinkedin}
Sign up to request clarification or add additional context in comments.

1 Comment

That's a great suggestion (y)
1

Is it possible?

No. This is not possible.

1 Comment

Sure, it wasn't.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.