Go Unmarshal nested unknown fields

心不动则不痛 提交于 2019-11-29 16:29:01

This is exactly what json.RawMessage is for (look at the unmarshal example in the docs). Unmarshal the top-level of the JSON Object first, inspect the kind field, then unmarshal the data field:

type Listing struct {                                           
    WhitelistStatus string  `json:"whitelist_status"`           
    Children        []Thing `json:"children"`                   
}                                                               

type T3 struct {                                                
    Domain              string `json:"domain"`                  
    CrosspostParentList []struct {                              
            Domain string `json:"domain"`                       
    } `json:"crosspost_parent_list"`                            
}                                                               

type Thing struct {
    Kind string      `json:"kind"`
    Data interface{} `json:"data"`
}

func (t *Thing) UnmarshalJSON(b []byte) error {
    var step1 struct {
            Kind string          `json:"kind"`
            Data json.RawMessage `json:"data"` 
    }

    if err := json.Unmarshal(b, &step1); err != nil {
            return err
    }

    var step2 interface{}
    switch step1.Kind {
    case "Listing":
            step2 = &Listing{}
    case "t3":
            step2 = &T3{}
    default:
            return errors.New("unknown kind: " + step1.Kind) // or simply ignore
    }

    if err := json.Unmarshal(b, step2); err != nil {
            return err
    }

    t.Kind = step1.Kind
    t.Data = step2

    return nil
}

Try it on the playground: https://play.golang.org/p/giBVT2IWPd-

In your case you needs to create a recursive function which will get the nested value of underlying interface{} till last depth. There is no way we can get nested value from interface{} with unknown underlying type. Here is an example of what you can do in your code

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