使用json.RawMessage捕获变化的字段。
使用json“-”名称对
DisplayName解码器隐藏字段。顶级JSON解码后,应用程序将填充此字段。
type MyListItem struct { Datestring `json:"date"` RawDisplayName json.RawMessage `json:"display_name"` DisplayName []string `json:"-"`}解组顶级JSON:
var li MyListItemif err := json.Unmarshal(data, &li); err != nil { // handle error}根据原始数据的类型取消对显示名称的编组:
if len(li.RawDisplayName) > 0 { switch li.RawDisplayName[0] { case '"': if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil { // handle error } case '[': var s []string if err := json.Unmarshal(li.RawDisplayName, &s); err != nil { // handle error } // Join arrays with "&" per OP's comment on the question. li.DisplayName = strings.Join(s, "&") }}游乐场的例子
将以上内容合并到for循环中以进行处理
MyListings:
var listings MyListingsif err := json.Unmarshal([]byte(data), &listings); err != nil { // handle error}for i := range listings.CLItems { li := &listings.CLItems[i] if len(li.RawDisplayName) > 0 { switch li.RawDisplayName[0] { case '"': if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil { // handle error } case '[': var s []string if err := json.Unmarshal(li.RawDisplayName, &s); err != nil { // handle error } li.DisplayName = strings.Join(s, "&") } }}游乐场的例子
如果数据模型中有多个位置,值可以是字符串或[]字符串,则将逻辑封装为类型可能会有所帮助。在json.Unmarshaler接口的实现中解析JSON数据。
type multiString stringfunc (ms *multiString) UnmarshalJSON(data []byte) error { if len(data) > 0 { switch data[0] { case '"': var s string if err := json.Unmarshal(data, &s); err != nil { return err } *ms = multiString(s) case '[': var s []string if err := json.Unmarshal(data, &s); err != nil { return err } *ms = multiString(strings.Join(s, "&")) } } return nil}像这样使用它:
type MyListItem struct { Date string `json:"date"` DisplayName multiString `json:"display_name"`}type MyListings struct { CLItems []MyListItem `json:"myitems"`}var listings MyListingsif err := json.Unmarshal([]byte(data), &listings); err != nil { log.Fatal(err)}操场上的例子



