我的类型MonthYear
定义为
type MonthYear time.Time
func (my *MonthYear) MarshalJSON() ([]byte, error) {
t := time.Time(*my)
return json.Marshal(&struct {
Month int `json:"month"`
Year int `json:"year"`
}{
Month: int(t.Month()) - 1,
Year: t.Year(),
})
}
我包括很多不同的结构,比如
type Event struct {
Name string `json:"name"`
Date MonthYear
}
type Item struct {
Category string `json:"category"`
Date MonthYear
}
如何内联MonthYear
类型以便生成的JSON没有任何嵌入对象?
我希望结果看起来像{ "name": "party", "month": 2, "year": 2017 }
和{ "category": "art", "month": 3, "year": 2016 }
,而不必为每个结构编写MarshalJSON。
答案 0 :(得分:3)
我知道这不是您希望收到的答案,但在encoding/json
包中添加内联支持之前,您可以使用以下解决方法:
使你的MonthYear
成为一个结构,例如:
type MonthYear struct {
t time.Time
Month int `json:"month"`
Year int `json:"year"`
}
一个可选的构造函数,可以轻松创建:
func NewMonthYear(t time.Time) MonthYear {
return MonthYear{
t: t,
Month: int(t.Month()) - 1,
Year: t.Year(),
}
}
并使用embedding(匿名字段)而不是常规(命名)字段来获得"展平" /在JSON表示中内联:
type Event struct {
Name string `json:"name"`
MonthYear
}
type Item struct {
Category string `json:"category"`
MonthYear
}
作为额外内容,您可以直接引用字段,例如Event.Year
或Event.Month
,这很不错。
测试它:
evt := Event{Name: "party", MonthYear: NewMonthYear(time.Now())}
fmt.Println(json.NewEncoder(os.Stdout).Encode(evt), evt.Year)
itm := Item{Category: "Tool", MonthYear: NewMonthYear(time.Now())}
fmt.Println(json.NewEncoder(os.Stdout).Encode(itm))
输出(在Go Playground上尝试):
{"name":"party","month":10,"year":2009}
<nil> 2009
{"category":"Tool","month":10,"year":2009}
<nil>
注意:MonthYear.t
时间字段在此处不起作用(它也没有被编组)。如果不需要原始time.Time
,您可以将其删除。