在Go语言中,我如何将json解组为对象数组? [英] In Go Language, how do I unmarshal json to array of object?

查看:439
本文介绍了在Go语言中,我如何将json解组为对象数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  {
我有以下JSON,我想将它解析到类的数组中: 1001:{level:10,monster-id:1001,skill-level:1,aimer-id:301}
1002:{level:12,技能水平:1,aimer-id:302}
1003:{level:16,monster-id:1003,skill-level :2,aimer-id:303}
}

这是我我试图做但失败:

$ p $ 类型怪物结构{
MonsterId int32
等级int32
SkillLevel int32
AimerId int32
}


类型MonsterCollection结构{
池映射[字符串]怪物
}

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

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

i:= 0
对于k,v:=范围m {

怪物:=新(怪物)
monster.Level = v [等级]
monster.MonsterId = v [怪物-id]
monster.SkillLevel = v [skill-level]
monster.AimerId = v [aimer-id]

mc.Pool [i] =怪物
i ++
}

}

编译器抱怨v [level]
<<无效操作。 index类型的接口()。

解决方案

这段代码有很多错误。首先,json不是有效的json。您缺少顶级对象中密钥对之间的逗号。

  {
1001:{
等级:10,
monster-id:1001,
技能等级:1,
aimer-id:301
},
1002:{
level:12,
monster-id:1002,
技能等级:1,
aimer-id:302
},
1003:{
等级:16,
monster-id:1003,
技能等级:2,
aimer-id:303
}
}






你的下一个问题(你询问的问题)是 m:= data。(map [string] interface {})使 m a map [string] interface {} 。这意味着,当您在范围循环中为 v 建立索引时,类型为 interface {} 。您需要使用 v。(map [string] interface {})再次输入断言,然后在您每次从地图上读取时输入assert。






我还注意到,当我尝试下一次尝试 mc.Pool [i] = monster 是一个int和mc.Pool是一个map [string]怪物。一个int不是该地图的有效键。






你的数据看起来很硬,所以我会让unmarshall做大部分为你工作。您可以为它提供一个map [string] Monster,而不是提供一个map [string] interface {}。

下面是一个简单的例子。除了改变解组的工作方式外,我还添加了错误返回。错误返回对于查找错误很有用。

 类型怪物结构{
MonsterId int32`json:这个错误返回是告诉我你有无效的json。 monster-id`
Level int32`json:level`
SkillLevel int32`json:skill-level`
AimerId int32`json:aimer-id`


类型MonsterCollection结构{
池映射[字符串]怪物
}

func(mc * MonsterCollection)FromJson(jsonStr string)错误{
var data =& mc.Pool
b:= [] byte(jsonStr)
return json.Unmarshal(b,data)
}

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


I have the following JSON, and I want to parse it into array of class:

{
    "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}
}

Here is what i am trying to do but failed:

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++
    }

}

The compiler complain about the v["level"] << invalid operation. index of type interface().

解决方案

This code has many errors in it. To start with, the json isn't valid json. You are missing the commas in between key pairs in your top level object. I added the commas and pretty printed it for you:

{
   "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
   }
}


Your next problem (the one you asked about) is that m := data.(map[string]interface{}) makes m a map[string]interface{}. That means when you index it such as the v in your range loop, the type is interface{}. You need to type assert it again with v.(map[string]interface{}) and then type assert each time you read from the map.


I also notice that you next attempt mc.Pool[i] = monster when i is an int and mc.Pool is a map[string]Monster. An int is not a valid key for that map.


Your data looks very rigid so I would make unmarshall do most of the work for you. Instead of providing it a map[string]interface{}, you can provide it a map[string]Monster.

Here is a quick example. As well as changing how the unmarshalling works, I also added an error return. The error return is useful for finding bugs. That error return is what told me you had invalid 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)
}

I posted a working example to goplay: http://play.golang.org/p/4EaasS2VLL

这篇关于在Go语言中,我如何将json解组为对象数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆