【问题标题】:In Go Language, how do I unmarshal json to array of object?在 Go 语言中,如何将 json 解组为对象数组?
【发布时间】:2013-06-05 04:20:34
【问题描述】:

我有以下 JSON,我想将其解析为类数组:

{
    "1001": {"level":10, "monster-id": 1001, "skill-level": 1, "aimer-id": 301}
    "1002": {"level":12, "monster-id": 1002, "skill-level": 1, "aimer-id": 302}
    "1003": {"level":16, "monster-id": 1003, "skill-level": 2, "aimer-id": 303}
}

这是我想做但失败的事情:

type Monster struct {
    MonsterId  int32
    Level      int32
    SkillLevel int32
    AimerId    int32
}


type MonsterCollection struct {
    Pool map[string]Monster
}

func (mc *MonsterCollection) FromJson(jsonStr string) {
    var data interface{}
    b := []byte(jsonStr)
    err := json.Unmarshal(b, &data)
    if err != nil {
        return
    }

    m := data.(map[string]interface{})

    i := 0
    for k, v := range m {

        monster := new(Monster)
        monster.Level = v["level"]
        monster.MonsterId = v["monster-id"]
        monster.SkillLevel = v["skill-level"]
        monster.AimerId = v["aimer-id"]

        mc.Pool[i] = monster
        i++
    }

}

编译器抱怨 v["level"]

【问题讨论】:

    标签: go


    【解决方案1】:

    这段代码有很多错误。首先,json 不是有效的 json。您缺少顶级对象中密钥对之间的逗号。我添加了逗号并为您漂亮地打印了它:

    {
       "1001":{
          "level":10,
          "monster-id":1001,
          "skill-level":1,
          "aimer-id":301
       },
       "1002":{
          "level":12,
          "monster-id":1002,
          "skill-level":1,
          "aimer-id":302
       },
       "1003":{
          "level":16,
          "monster-id":1003,
          "skill-level":2,
          "aimer-id":303
       }
    }
    

    你的下一个问题(你问的那个)是m := data.(map[string]interface{}) 使m 成为map[string]interface{}。这意味着当您在范围循环中对它进行索引时,例如v,类型为interface{}。您需要使用 v.(map[string]interface{}) 再次键入 assert 它,然后每次从地图中读取时键入 assert。


    我还注意到,当 i 是 int 并且 mc.Pool 是 map[string]Monster 时,您下一次尝试 mc.Pool[i] = monster。 int 不是该映射的有效键。


    您的数据看起来很死板,所以我会让 unmarshall 为您完成大部分工作。您可以为其提供 map[string]Monster,而不是为其提供 map[string]interface{}。

    这是一个简单的例子。除了更改解组的工作方式外,我还添加了一个错误返回。错误返回对于查找错误很有用。该错误返回告诉我您的 json 无效。

    type Monster struct {
        MonsterId  int32 `json:"monster-id"`
        Level      int32 `json:"level"`
        SkillLevel int32 `json:"skill-level"`
        AimerId    int32 `json:"aimer-id"`
    }
    
    type MonsterCollection struct {
        Pool map[string]Monster
    }
    
    func (mc *MonsterCollection) FromJson(jsonStr string) error {
        var data = &mc.Pool
        b := []byte(jsonStr)
        return json.Unmarshal(b, data)
    }
    

    我在 goplay 上发布了一个工作示例:http://play.golang.org/p/4EaasS2VLL

    【讨论】:

    • 哇,非常感谢。我只是在学习 GO 语言,还有很多东西要学。你的回答很有帮助!
    • 还有一个问题,无论如何我可以使用 int32 作为地图的键吗?在这种情况下,值应该是 monster-id 但是当我将类型更改为 int32 时,示例代码会出错。
    • JSON 键必须是字符串。你需要做的是首先解析成map[string]Monster,然后将每个怪物复制到map[int]Monster
    • play.golang.org/p/iJN4P1ImOm 这是如何将其转换为 uint32 的示例。
    【解决方案2】:

    稍微偏向一侧 - 当您需要地图时,您要求提供一组对象

    如果你需要一个数组(实际上是一个切片)

    http://ioblocks.blogspot.com/2014/09/loading-arrayslice-of-objects-from-json.html

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 2017-12-06
      • 2018-11-13
      • 2015-03-31
      • 2018-05-06
      • 2012-12-14
      • 1970-01-01
      • 2014-12-02
      • 2017-07-11
      相关资源
      最近更新 更多