Igg*_*lob 2 generics json marshalling go
我的数据模型定义了多个结构,它们都有两个共同的字段:a StartDate和an EndDate.我需要将这两个字段格式化为2018-09-21编组的JSON,因此结构实现了Marshaller接口:
type Results struct {
Source string `json:"source"`
StartDate time.Time
EndDate time.Time
}
type WeightedResults struct {
Source string `json:"source"`
StartDate time.Time
EndDate time.Time
}
func (r Results) MarshalJSON() ([]byte, error) {
type Alias Results
if equalDate(r.StartDate, r.EndDate) {
return json.Marshal(&struct {
Date string `json:"date"`
Alias
}{
Date: r.StartDate.Format(dateFormat),
Alias: (Alias)(r),
})
}
return json.Marshal(&struct {
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Alias
}{
StartDate: r.StartDate.Format("2006-01-02"),
EndDate: r.EndDate.Format("2006-01-02"),
Alias: (Alias)(r),
})
}
func (r WeightedResults) MarshalJSON() ([]byte, error) {
type Alias WeightedResults
if equalDate(r.StartDate, r.EndDate) {
return json.Marshal(&struct {
Date string `json:"date"`
Alias
}{
Date: r.StartDate.Format(dateFormat),
Alias: (Alias)(r),
})
}
return json.Marshal(&struct {
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Alias
}{
StartDate: r.StartDate.Format("2006-01-02"),
EndDate: r.EndDate.Format("2006-01-02"),
Alias: (Alias)(r),
})
}
Run Code Online (Sandbox Code Playgroud)
上面的解决方案工作正常,但产生了大量的代码重复.有没有办法重构两种实现MarshalJSON使用相同的逻辑/代码?我很清楚Go还没有提供Generics(但是),但是必须有另一种解决这个问题的方法,对吧?
您的自定义封送程序不应位于结构上,而应位于嵌入的自定义类型上time.Time:
type MyTime struct {
time.Time
}
func (t MyTime) MarshalJSON() ([]byte, error) {
return json.Marshal(t.Format("2006-01-02"))
}
Run Code Online (Sandbox Code Playgroud)
然后在任何地方使用此类型.
type Results struct {
Source string `json:"source"`
StartDate MyTime
EndDate MyTime
}
Run Code Online (Sandbox Code Playgroud)