【问题标题】:How can I turn map[string]interface{} to different type of struct?如何将 map[string]interface{} 转换为不同类型的结构?
【发布时间】:2014-08-08 07:03:56
【问题描述】:

我正在调用一个 API,它将像这样返回 Json 对象:

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

根据不同的类型,这个对象会有不同种类的字段,但是这些字段对于不同的类型是确定的。 因此,我将 Json 字符串解组为 map[string]interface{} 以获取不同的类型,但是如何将这些 map[string]interface{} 转换为某个结构?

  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
  }

【问题讨论】:

    标签: json go


    【解决方案1】:

    对于这种两步 json 解码,您可能需要查看 json.RawMessage。它允许您延迟处理部分 json 响应。文档中的示例显示了如何操作。

    【讨论】:

      【解决方案2】:

      一种方法是使用一个将地图作为输入参数的构造函数(以New… 开头的函数)。

      第二种方法,在我看来要慢得多,是重新解组到正确的结构类型。

      【讨论】:

        【解决方案3】:

        如果类型足够不同并且你想偷懒,你可以尝试以每种格式对其进行解码:

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

        如果对象相似或者你想不那么懒惰,你可以解码类型然后做一些事情:

          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
          }
        
        

        【讨论】:

          猜你喜欢
          • 2015-01-14
          • 2021-05-26
          • 2018-08-28
          • 2022-07-06
          • 2020-09-23
          • 2018-12-20
          • 1970-01-01
          • 2021-05-11
          相关资源
          最近更新 更多