英文:
GoLang: Refactoring xml tag definition in struct
问题
在上面的示例中,我在多个结构体中重复使用了xml:"facebook"
。我想知道是否可以将其提取为常量,并在所有结构体中引用它。
或者这是我必须定义结构体的方式,我已经阅读了规范/文档,但没有找到任何特定的方法来实现这一点。
这种可能吗?
PS:我的意图是减少重复的代码,因为在创建新的结构体时很容易出现输入错误(我已经遇到过几次)。
英文:
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).
答案1
得分: 2
这是要翻译的内容:
每当需要时,重复使用tag并不麻烦。请注意,规范不允许在为结构字段定义标签时使用常量或变量。结构标签只能是字符串字面量。引用自规范:结构类型:
> 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"`
}
测试这两种类型(Social
和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>`
输出结果(在Go Playground上尝试):
&{XMLName:{Space: Local:social} HasFacebook:{Facebook:someface} Twitter:sometwitter Youtube:}
&{HasFacebook:{Facebook:someface} Linkedin:somelinkedin}
英文:
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}
答案2
得分: 1
不可能。这是不可能的。
英文:
> Is it possible?
No. This is not possible.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论