假设我有以下内容:
type My struct{
First string `xml:"first"`
Last string `xml:"name"`
...many more tags...
}
我想将所有标签的前缀更改为“ mycustomtag”。我见过https://stackoverflow.com/a/42549826/522962,但这描述了一种手动方式,其中您手动定义了带有标签的第二个结构。我如何自动这样做?
例如我想在下面给出类似的内容,但是由于有很多字段,我该怎么做,所以我不必手动进行操作:
// how do I do the next part automagically????
func (m *My) MarshalJSON() ([]byte, error) {
type alias struct {
First string `mycustomtag:"first"`
Last string `mycustomtag:"name"`
...many more tags...
}
var a alias = alias(*m)
return json.Marshal(&a)
}
答案 0 :(得分:2)
如果这不是在运行时,而是静态地修改代码源,则可以使用fatih/gomodifytags
。
请参见“ Writing a Go Tool to Parse and Modify Struct Tags”
结构字段标记是编码/解码类型的重要组成部分,尤其是在使用诸如encoding / json之类的包时。
但是,修改标签是重复的,麻烦的,而且容易出现人为错误。
我们可以使用专门为此目的而编写的自动化工具来轻松修改标签。
答案 1 :(得分:1)
如果需要,您还可以在运行时使用reflect进行操作。
func (m *My) MarshalJSON() ([]byte, error) {
oldtype := reflect.TypeOf(*m)
fields := make([]reflect.StructField, oldtype.NumField())
for i := 0; i < oldtype.NumField(); i++ {
field := oldtype.Field(i)
if _, ok := field.Tag.Lookup("xml"); ok {
field.Tag = reflect.StructTag(strings.Replace(string(field.Tag), "xml", "json", 1))
}
fields[i] = field
}
newtype := reflect.StructOf(fields)
a := reflect.ValueOf(*m).Convert(newtype).Interface()
return json.Marshal(&a)
}