2013-06-05 12 views
10

Ho il seguente JSON, e voglio analizzare in array di classe:In Go Language, come faccio a fare un array unson a un array di oggetti?

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

Ecco quello che sto cercando di fare, ma non è riuscito:

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

} 

Il compilatore lamentano la v ["livello"] < < operazione non valida. indice di tipo interface().

risposta

18

Questo codice contiene molti errori. Per cominciare, il json non è valido JSON. Ti mancano le virgole tra le coppie di chiavi nell'oggetto di livello superiore. Ho aggiunto le virgole e graziosa stampato per voi:

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

vostro prossimo problema (quello che ha chiesto circa) è che rende m := data.(map[string]interface{})m un map[string]interface{}. Ciò significa che quando lo indicizzi come lo v nel tuo intervallo, il tipo è interface{}. È necessario digitare asserirlo di nuovo con v.(map[string]interface{}) e quindi digitare asser ogni volta che si legge dalla mappa.


Ho anche notato che il prossimo tentativo mc.Pool[i] = monster quando i è un int e mc.Pool è una mappa [stringa] mostro. Un int non è una chiave valida per quella mappa.


I dati sembra molto rigida quindi vorrei fare unmarshall fare la maggior parte del lavoro per voi. Invece di fornirgli un'interfaccia [stringa] mappa {}, puoi fornirle una mappa [stringa] Mostro.

Ecco un breve esempio. Oltre a modificare il funzionamento di Unmarshalling, ho anche aggiunto un errore. Il ritorno dell'errore è utile per trovare bug. Quel ritorno di errore è quello che mi ha detto che hai avuto un jono non valido.

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

ho postato un esempio di lavoro per goplay: http://play.golang.org/p/4EaasS2VLL

+0

wow, grazie mille. Sto solo imparando il GO lang e ho ancora tanto da imparare. La tua risposta è molto utile! – Nick

+0

ancora una domanda, c'è comunque io posso usare int32 per la chiave della mappa? il valore dovrebbe essere monster-id è questo caso ma quando cambio il tipo in int32, il codice di esempio dà errore. – Nick

+3

Le chiavi JSON devono essere stringhe. Quello che devi fare è prima analizzare un 'map [string] Monster' e quindi copiare ciascun mostro in un' map [int] Monster'. –

Problemi correlati