How to unmarshal nested unknown fields

后端 未结 2 1976
北海茫月
北海茫月 2020-12-22 02:05

I forked a great project here, and have just been having a mess around with it learning some go. My issue I can\'t figure out is some things about custom unmarshaling, if yo

相关标签:
2条回答
  • 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-

    0 讨论(0)
  • 2020-12-22 03:02

    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

    0 讨论(0)
提交回复
热议问题