簡體   English   中英

封送JSON時如何內聯字段?

[英]How do I inline fields when marshalling JSON?

我有一個類型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。

我知道這不是您希望收到的答案,但是在將內聯支持添加到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(),
    }
}

並使用嵌入 (匿名字段)代替常規(命名字段)來在JSON表示形式中“扁平化” /內聯:

type Event struct {
    Name string `json:"name"`
    MonthYear
}

type Item struct {
    Category string `json:"category"`
    MonthYear
}

另外,您將能夠直接引用諸如Event.YearEvent.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是沒有必要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM