【问题标题】:golang json unmarshal part of map[string]interface{}golang json 解组 map[string]interface{} 的一部分
【发布时间】:2014-04-23 15:51:39
【问题描述】:

我有以下代码尝试解组此 json 文件,但是 json.Unmarshal([]byte(msg["restaurant"]), &restaurant) 行总是出错。如何让 Unmarshal 忽略“restaurant”或仅将“restaurant”数据传递给 Unmarshal 函数?

谢谢!

{
  "restaurant": {
    "name": "Tickets",
    "owner": {
      "name": "Ferran"
    }
  }
}


    file, e := ioutil.ReadFile("./rest_read.json")
    if e != nil {
            fmt.Println("file error")
            os.Exit(1)
    }

    var data interface{}
    json.Unmarshal(file, &data)

    msg := data.(map[string]interface{})
    log.Println(msg)
    log.Println(msg["restaurant"])
    log.Println(reflect.TypeOf(msg["restaurant"]))

    var restaurant Restaurant
    json.Unmarshal([]byte(msg["restaurant"]), &restaurant)

    log.Println("RName: ", restaurant.Name)
    log.Println("Name: ", restaurant.Owner.Name)

【问题讨论】:

    标签: json go


    【解决方案1】:

    我建议为您的数据构建一个合适的模型。这将使您能够干净地将数据解组到 Go 结构中。

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Restaurant struct {
        Restaurant RestaurantData `json:"restaurant"`
    }
    
    type RestaurantData struct {
        Name  string `json:"name"`
        Owner Owner  `json:"owner"`
    }
    
    type Owner struct {
        Name string `json:"name"`
    }
    
    func main() {
        data := `{"restaurant":{"name":"Tickets","owner":{"name":"Ferran"}}}`
        r := Restaurant{}
        json.Unmarshal([]byte(data), &r)
    
        fmt.Printf("%+v", r)
    }
    

    【讨论】:

      【解决方案2】:

      可以通过解码到接口然后从结果中提取顶级映射来进行通用解组ala gson,例如:

      var msgMapTemplate interface{}
      err := json.Unmarshal([]byte(t.ResponseBody), &msgMapTemplate)
      t.AssertEqual(err, nil)
      msgMap := msgMapTemplate.(map[string]interface{})
      

      请参阅http://blog.golang.org/json-and-go 中的“解码任意数据”了解更多信息。

      【讨论】:

      • 好答案!有时制作一个模型来进行严格的 Unmarshalling 是一件很痛苦的事情。
      【解决方案3】:

      解组以递归方式发生,因此msg["restaurant"] 不再是 json 字符串 - 它是另一个 map[string]interface{}。如果您想直接解组为 Restaurant 对象,则必须提供一个带有 Restaurant 成员的简单包装器对象并解组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-27
        • 2021-01-02
        • 1970-01-01
        • 2015-01-14
        • 2013-05-30
        • 1970-01-01
        • 1970-01-01
        • 2019-01-05
        相关资源
        最近更新 更多