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!
To unmarshal JSON into a pointer, Unmarshal first handles the case of the JSON being the JSON literal null. In that case, Unmarshal sets the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into the value pointed at by the pointer. If the pointer is nil, Unmarshal allocates a new value for it to point to.
Unmarshal is the contrary of marshal. It allows you to convert byte data into the original data structure. In go, unmarshaling is handled by the json. Unmarshal() method.
Marshal and Unmarshal convert a string into JSON and vice versa. Encoding and decoding convert a stream into JSON and vice versa.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With