简体   繁体   中英

How can I turn map[string]interface{} to different type of struct?

I'm calling an API which will return Json objects like this:

{
  name: "XXX"
  type: "TYPE_1"
  shared_fields: {...}
  type_1_fields: {...}
  ..
  type_2_fields: {...}
}

Based on different types, this object will have different kinds of fields, but these fields are certain for different types. So, I unmarshal the Json string to map[string]interface{} to fetch the the different type but how can I turn these map[string]interface{} to a certain struct?

  var f map[string]interface{}
  err := json.Unmarshal(b, &f)
  type := f["type"]
  switch type {
    case "type_1":
      //initialize struct of type_1
    case "type_2":
      //initialize struct of type_2
  }

For this sort of two-step json decoding you will probably want to check out json.RawMessage . It allows you to defer processing of parts of your json response. The example in the docs shows how.

One way to do it would be to have a constructor function (one that starts with New… ) that takes a map as input parameter.

A second way, much slower in my opinion, would be to redo the unmarshalling to the right struct type.

If the types are different enough and you want to be lazy you can just try to decode it in each format:

  f1 := type1{}
  err := json.Unmarshal(b, &f1)
  if err == nil {
      return f1
  }
  f2 := type2{}
  err := json.Unmarshal(b, &f2)
  if err == nil {
     return f2
  }
  ...

If the objects are similar or you want to be less lazy, you could just decode the type and then do something:

  type BasicInfo struct {
     Type string `json:"type"`
  }

  f := BasicInfo{}
  err := json.Unmarshal(b, &f)
  switch f.Type {
    case "type_1":
      //initialize struct of type_1
    case "type_2":
      //initialize struct of type_2
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM