[英]Why does encoding JSON struct members not invoking custom MarshalJSON?
[英]Can I use MarshalJSON to add arbitrary fields to a json encoding in golang?
假設我已經編寫了以下代碼片段。 此處的操場上的完整代碼適合那些有興趣的人。
type Book struct {
Title string
Author string
}
func main() {
ms := Book{"Catch-22", "Joseph Heller"}
out, err := json.MarshalIndent(ms, "", " ")
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(out))
}
此代碼輸出以下內容,完全符合我的預期:
{
"Title": "Catch-22",
"Author": "Joseph Heller"
}
假設有一段時間我想向 JSON 輸出添加一個字段,但不將其包含在Book
結構中。 也許是一種類型:
{
"Title": "Catch-22",
"Author": "Joseph Heller",
"Genre": "Satire"
}
我可以使用MarshalJSON()
向Marshal()
上的 JSON 負載添加任意字段嗎? 就像是:
func (b *Book) MarshalJSON() ([]byte, error) {
// some code
}
其他答案讓我認為這應該是可能的,但我正在努力弄清楚實現。
這是一個比我上一個更好的答案。
type FakeBook Book
func (b Book) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
FakeBook
Genre string
}{
FakeBook: FakeBook(b),
Genre: "Satire",
})
}
由於匿名結構字段是“合並的”(有一些額外的考慮),我們可以使用它來避免重新映射單個字段。 請注意使用FakeBook
類型來避免否則會發生的無限遞歸。
這個問題的一個可能答案是結構文字(此處的代碼),盡管我希望有一些更通用的東西,它不需要重新映射結構的所有字段:
func (b *Book) MarshalJSON() ([]byte, error) {
return json.Marshal(struct{
Title string
Author string
Genre string
} {
Title: b.Title,
Author: b.Author,
Genre: "Satire",
})
}
編組map
是解決問題的另一種方法。
tmap := make(map[string]interface{})
tmap["struct"] = struct {
StructValue string `json:"struct_value"`
}{
"Value 02",
}
tmap["string"] = "Value 01"
out, err := json.MarshalIndent(tmap, "", " ")
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(out))
這將輸出:
{
"string": "Value 01",
"struct": {
"struct_value": "Value 02"
}
}
如果您有許多任意鍵名,這可能是一個很好的解決方案。
這是處理它的一種方法:
type Object struct {
A string
B int
Extra map[string]interface{} `json:"-"`
}
func (o Object) MarshalJSON() ([]byte, error) {
type Object_ Object
b, err := json.Marshal(Object_(o))
if err != nil {
return nil, err
}
if o.Extra == nil || len(o.Extra) == 0 {
return b, nil
}
m, err := json.Marshal(o.Extra)
if err != nil {
return nil, err
}
if len(b) == 2 {
return m, nil
} else {
b[len(b)-1] = ','
return append(b, m[1:]...), nil
}
}
您可以將任何其他字段添加到Extra
地圖,它們將顯示在輸出中而不會嵌套。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.