2014-04-23 11 views
8

Ho questo structQual è il modo corretto per convertire un json.RawMessage in una struct?

type SyncInfo struct { 
    Target string 
} 

Ora mi tua ricerca alcuni dati json da elasticsearch. Source è di tipo json.RawMessage. Tutto quello che voglio è quello di mappare source al mio SyncInfo che ho creato la variabile mySyncInfo per.

Ho persino capito come farlo ... ma sembra strano. Prima chiamo MarshalJSON() per ottenere un []byte e poi lo invii a json.Unmarshal() che prende uno []byte e un puntatore alla mia struct.

Questo funziona bene ma sembra che sto facendo un salto extra. Mi manca qualcosa o è il modo previsto per passare da json.RawMessage a struct?

var mySyncInfo SyncInfo 

jsonStr, _ := out.Hits.Hits[0].Source.MarshalJSON() 
json.Unmarshal(jsonStr, &mySyncInfo) 

fmt.Print(mySyncInfo.Target) 

risposta

13

Come detto, il tipo sottostante di json.RawMessage è []byte, in modo da poter utilizzare un json.RawMessage come parametro dati json.Unmarshal.

Tuttavia, il tuo problema è che hai un puntatore (*json.RawMessage) e non un valore. Tutto quello che dovete fare è dereferenziarlo:

err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo) 

esempio di lavoro:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type SyncInfo struct { 
    Target string 
} 

func main() { 
    data := []byte(`{"target": "localhost"}`) 
    Source := (*json.RawMessage)(&data) 

    var mySyncInfo SyncInfo 
    // Notice the dereferencing asterisk * 
    err := json.Unmarshal(*Source, &mySyncInfo) 
    if err != nil { 
     panic(err) 
    } 

    fmt.Printf("%+v\n", mySyncInfo) 
} 

uscita:

{Target:localhost} 

Playground:http://play.golang.org/p/J8R3Qrjrzx

+2

tada! Tu sei l'uomo! È il mio primo giorno con Go ;-) – Christoph

+0

Benvenuto :) E felice Go codifica! – ANisus

2

json.RawMessage è in realtà solo una porzione di byte. Dovreste essere in grado di alimentare direttamente in json.Unmarshal direttamente, in questo modo:

json.Unmarshal(out.Hits.Hits[0].Source, &mySyncInfo) 

Inoltre, un po 'estraneo, ma json.Unmarshal può restituire un errore e si desidera gestire questo.

err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo) 
if err != nil { 
    // Handle 
} 
+0

Questo mi dà un errore di tipo 'impossibile usare hit.Source (tipo * json.RawMessage) come tipo [] byte nell'argomento di funzione' – Christoph

+0

Ah, dobbiamo fare riferimento al valore direttamente allora. Prova a passare * json.RawMessage invece di json.RawMessage. Ho aggiornato l'esempio nella risposta per riflettere questo cambiamento. –

Problemi correlati