2013-04-14 17 views
7

voglio deserialise un oggetto che include una matrice di una certa interfaccia Entity:Unmarshal una matrice JSON di struct eterogenei

type Result struct { 
    Foo int; 
    Bar []Entity; 
}; 

Entity è un'interfaccia implementata da un certo numero di tipi struct. I dati JSON identificano il tipo di struttura con un campo "tipo" in ciascuna entità. Per esempio.

{"type":"t1","field1":1} 
{"type":"t2","field2":2,"field3":3} 

Come potrei fare per deserialising tipo Result in modo tale che si popola correttamente la matrice. Da quello che posso vedere, devo:

  1. Implementare UnmarshalJSON su Result.
  2. Parse Bar come []*json.RawMessage.
  3. Analizza ogni messaggio non elaborato come map[string]interface{}.
  4. Controllare il campo "tipo" nel messaggio non elaborato.
  5. Creare una struttura di tipo appropriato.
  6. Analizza il messaggio non elaborato di nuovo, questa volta nella struttura appena creata.

Questo suona tutto molto noioso e noioso. C'è un modo migliore per farlo? O lo sto facendo all'indietro, e c'è un metodo più canonico per gestire una serie di oggetti eterogenei?

risposta

5

Penso che il tuo processo sia probabilmente un po 'più complicato di quanto debba essere, vedi http://play.golang.org/p/0gahcMpuQc. Una singola interfaccia [stringa] {} della mappa ne gestirà molto per te.

In alternativa, si potrebbe fare un tipo come

struct EntityUnion { 
    Type string 
    // Fields from t1 
    // Fields from t2 
    // ... 
} 

Unmarshal in quella; imposterà la stringa Type e riempirà tutti i campi che può ottenere dai dati JSON. Quindi hai solo bisogno di una piccola funzione per copiare i campi nel tipo specifico.

+0

Ho finito con una struttura "unione". Sembrava sporco, ma alla fine è stato liberatorio. –