json unmarshal embedded struct

僤鯓⒐⒋嵵緔 提交于 2019-12-22 08:15:12

问题


I would like to unmarshal to struct Outer defined as:

type Outer struct {
    Inner
    Num int
}

type Inner struct {
    Data string
}
func (i *Inner) UnmarshalJSON(data []byte) error {
    i.Data = string(data)
    return nil
}

Using json.Unmarshal(data, &Outer{}) seems only to use Inner's UnmarshalJSON and ignores the Num field: https://play.golang.org/p/WUBfzpheMl

I have an unwieldy solution where I set the Num field manually, but I was wondering if anybody had a cleaner or simpler way to do it.

Thanks!


回答1:


This is happening because Inner is being embedded in Outer. That means when json library calls unmarshaler on Outer, it instead ends up calling it on Inner.

Therefore, inside func (i *Inner) UnmarshalJSON(data []byte), the data argument contains the entire json string, which you are then processing for Inner only.

You can fix this by making Inner explicit field in Outer

Outer struct {
    I Inner // make Inner an explicit field
    Num int `json:"Num"`
}

Working example




回答2:


You shouldn't need an unmarshalling function

https://play.golang.org/p/-HZwX5-rPD

Edit: Here is a more complete example

https://play.golang.org/p/oz5kiwy3_K




回答3:


Just delete UnmarshalJSON in your example because it's used in unmarshaling of Outer since Inner is inlined. Otherwise, you need to override it if you want to do something custom.

https://play.golang.org/p/D6V6vKpx9J




回答4:


Actually you not need explicit field, you need properly Marshal/UnMarshal

Example: https://play.golang.org/p/mWPM7m44wfK

package main

import (
    "encoding/json"
    "fmt"
)

type Outer struct {
    Inner
    Num int `json:"Num"`
}

type Inner struct{ Data string }

type InnerRaw struct {Data string}

func (i *Inner) UnmarshalJSON(data []byte) error {
    ir:=&InnerRaw{}
    json.Unmarshal(data, ir)
    i.Data = ir.Data
    return nil
}

func main() {
    x := Outer{}
    data := []byte(`{"Num": 4, "Data":"234"}`)
    _ = json.Unmarshal(data, &x)
    fmt.Printf("%+v\n", x)
    js, _:=json.Marshal(x)
    fmt.Printf("JSON:%s", string(js))
}


来源:https://stackoverflow.com/questions/38982445/json-unmarshal-embedded-struct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!