В языке Go, как мне отменить 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}
}

Вот что я пытаюсь сделать, но не удалось:

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" ] & Л; < недействительная операция. индекс типа interface().

Ответ 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 a map[string]interface{}. Это означает, что когда вы индексируете его, например v в вашем цикле диапазона, тип interface{}. Вам нужно снова ввести подтверждение с помощью v.(map[string]interface{}), а затем введите assert каждый раз, когда вы читаете с карты.


Я также замечаю, что следующая попытка mc.Pool[i] = monster, когда я - это int, а mc.Pool - это карта [string] Monster. Значение int не является допустимым ключом для этой карты.


Ваши данные выглядят очень жесткими, поэтому я бы сделал unmarshall большую часть работы для вас. Вместо того, чтобы предоставить ему интерфейс карты [string] {}, вы можете предоставить ему карту [string] Monster.

Вот краткий пример. Помимо изменения способа работы с unmarshalling, я также добавил сообщение об ошибке. Возврат ошибки полезен для поиска ошибок. Эта ошибка возвращает то, что сказал мне, что у вас был недействительный 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