json unmarshal embedded struct

≡放荡痞女 提交于 2019-12-05 17:29:01

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

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

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

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