编组结构体时间的通用方法。使用自定义格式将时间字段转换为 JSON

问题描述 投票:0回答:1

我的数据模型定义了多个结构,这些结构都有两个共同字段:a

StartDate
EndDate
。我需要在编组 JSON 中将这两个字段格式化为
2018-09-21
,因此结构实现
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),
    })
}

上面的解决方案工作正常,但会产生大量代码重复。有没有办法重构

MarshalJSON
的两个实现以使用相同的逻辑/代码?我很清楚 Go 还没有提供泛型,但是必须有另一种方法来解决这个问题,对吗?

json go marshalling
1个回答
6
投票

您的自定义封送拆收器不应位于结构上,而应位于嵌入的自定义类型上

time.Time
:

type MyTime struct {
    time.Time
}

func (t MyTime) MarshalJSON() ([]byte, error) {
    return json.Marshal(t.Format("2006-01-02"))
}

然后在任何你想要的地方使用这种类型。

type Results struct {
    Source     string    `json:"source"`
    StartDate  MyTime
    EndDate    MyTime
}
© www.soinside.com 2019 - 2024. All rights reserved.