2013-06-05 7 views
10

Mam następujące JSON i chcę, aby przetworzyć je w tablicy Klasa:W Go Język, w jaki sposób mogę unmarshal json do tablicy obiektu?

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

Oto co próbuję zrobić, ale nie powiodło się:

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

} 

Kompilator narzekać v ["poziom"] < < nieprawidłowa operacja. indeks typu interface().

Odpowiedz

18

Ten kod ma wiele błędów. Na początek json nie jest prawidłowy json. Brakuje przecinków między parami kluczy w obiekcie najwyższego poziomu. Dodałem przecinki i dość wydrukowane to dla ciebie:

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

Następnym problemem (jeden pytasz o) jest to, że m := data.(map[string]interface{}) sprawia mmap[string]interface{}. Oznacza to, że podczas indeksowania, na przykład v w pętli zasięgu, typem jest interface{}. Musisz wpisać ponownie przy pomocy v.(map[string]interface{}), a następnie wpisz za każdym razem, gdy czytasz z mapy.


Ja również zauważyć, że następna próba mc.Pool[i] = monster kiedy jest int i mc.Pool jest mapa [ciąg] Monster. Wartość int nie jest poprawnym kluczem dla tej mapy.


Twoje dane wyglądają bardzo sztywno, więc chciałbym, aby unmarshall wykonał większość pracy za Ciebie. Zamiast dostarczać mu mapę [string] interface {}, możesz podać mu mapę [string] Monster.

Oto krótki przykład. Oprócz zmiany sposobu anulowania, dodałem również błąd. Zwrot błędów jest przydatny do wyszukiwania błędów. Ten powrót błędu powiedział mi, że masz nieprawidłowy 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) 
} 

Zamieściłem pracy przykład do goplay: http://play.golang.org/p/4EaasS2VLL

+0

wow, bardzo dziękuję. Właśnie uczę się GO Lang i wciąż mam tyle do nauki. Twoja odpowiedź jest bardzo pomocna! – Nick

+0

jeszcze jedno pytanie, czy mimo to mogę użyć int32 dla klucza mapy? wartość powinna być monster-id w tym przypadku, ale kiedy zmienię typ na int32, przykładowy kod daje błąd. – Nick

+3

Klucze JSON muszą być ciągami. To, co musisz zrobić, to najpierw przeanalizować w 'map [string] Monster', a następnie skopiować każdy potwór do' map [int] Monster'. –

Powiązane problemy