2013-08-17 19 views
5

Here is the codeUnmarshal sul valore riflette

package main 

import (
    "fmt" 

    "encoding/json" 
    "reflect" 
) 

var (
    datajson []byte 
    //ref mapp 
) 

type mapp map[string]reflect.Type 

type User struct { 
    Name string 
    //Type map[string]reflect.Type 
} 

func MustJSONEncode(i interface{}) []byte { 
    result, err := json.Marshal(i) 
    if err != nil { 
     panic(err) 
    } 
    return result 
} 
func MustJSONDecode(b []byte, i interface{}) { 
    err := json.Unmarshal(b, i) 
    if err != nil { 
     panic(err) 
    } 

} 
func Store(a interface{}) { 
    datajson = MustJSONEncode(a) 
    //fmt.Println(datajson) 
} 

func Get(a []byte, b interface{}) { 
    objType := reflect.TypeOf(b).Elem() 
obj := reflect.New(objType) 
//fmt.Println(obj) 
MustJSONDecode(a, &obj) 
fmt.Printf("%s", obj) 
    } 

func main() { 

    dummy := &User{} 
    david := User{Name: "DavidMahon"} 

    Store(david) 
    Get(datajson, dummy) 

} 

In funzione Get

func Get(a []byte, b interface{}) { 
    objType := reflect.TypeOf(b).Elem() 
obj := reflect.New(objType) 
//fmt.Println(obj) 
MustJSONDecode(a, &obj) 
fmt.Printf("%s", obj) 
    } 

non riesco a unmarshal il json nel tipo oggetto sottostante.

Cosa c'è di sbagliato qui? Sono così bloccato qui. Qualcosa di molto semplice ma così difficile da capire.

Grazie

UPDATE :: Obiettivo di questo problema è quello di prelevare un oggetto completamente formato di tipo passata in funzione Get.

L'approccio menzionato da Nick nel commento riportato di seguito non mi consente di ottenere l'oggetto effettivo che ho già provato in precedenza. Posso comunque recuperare i dati (anche quando l'oggetto ha oggetti ricorsivi sotto) in una mappa come questo

func Get(a []byte) { 
    var f interface{} 

    //buf := bytes.NewBuffer(a) 
    //v := buf.String() 
    //usr := &User{} 

    MustJSONDecode(a, &f) 
    fmt.Printf("\n %v \n", f) 
} 

Tuttavia ho bisogno l'oggetto reale di nuovo non solo i dati. Qualcosa come user := &User{"SomeName"} dove ho bisogno di user oggetto da Unmarshall. Il trucco è da qualche parte nel riflesso ma non so come.

+0

Riflettere non farà quello che sembra pensarlo. Non puoi costruire un oggetto arbitrario usandolo. Potresti probabilmente intrappolare qualcosa usando riflessi e non sicuri, ma in realtà dovresti ripensare a ciò che stai cercando di fare. –

+0

Grazie sto chiudendo questa discussione. Grazie per aver dedicato tempo. Ha fatto +1 sulle tue risposte – Minty

risposta

3

sono confusa sul motivo per cui si vuole fare questo, ma ecco come risolvere il problema

func Get(a []byte, b interface{}) { 
    objType := reflect.TypeOf(b).Elem() 
    obj := reflect.New(objType).Interface() 
    //fmt.Println(obj) 
    MustJSONDecode(a, &obj) 
    fmt.Printf("obj = %#v\n", obj) 
} 

nota la chiamata a Interface().

Playground link

Mi sembra che si sta andando a un sacco di problemi a fare un vuoto &User quando ne avete già uno in b, ad esempio

func Get(a []byte, b interface{}) { 
    MustJSONDecode(a, &b) 
    fmt.Printf("obj = %#v\n", b) 
} 

ma credo ci sia un po 'di più a questo piano che non è evidente qui!

+0

Grazie, ma ho già provato il trucco Thsat.Ci sono due problemi con questo. – Minty

+0

1. Non funzionerà su tipi di oggetti ricorsivi. Questo è oggetti all'interno di oggetti e 2. I dati restituiti non sono un oggetto di tipo inviato in Get funtion. Questa è la parte difficile. Ho aggiornato la mia domanda per chiarirlo. – Minty

+0

Quale oggetto restituito? Non si restituisce un oggetto. b che è già il tipo giusto viene popolato dalla chiamata a MustJSONDecode. –

1

reflect.New(objType) restituisce un reflect.Value Quale non è la cosa come l'interfaccia che hai passato. Secondo i documenti per Value È una struttura con solo campi non esportati. il pacchetto json non può funzionare con campi non esportati. Dal momento che non è lo stesso oggetto in cui sei passato e non è nemmeno codificabile/decodificabile con JSON, il pacchetto JSON fallirà.

Probabilmente troverai l'articolo Laws of Reflection utile durante il tentativo di utilizzare il pacchetto reflect.

+0

Grazie per il riferimento. Ho letto tre volte, ma uno pensa che ho notato che questo articolo (che è molto intimidatorio) non parla della creazione di oggetti da altri oggetti. Può l'autore tenerlo come parte della discrezione degli sviluppatori. – Minty

+1

Non si può realmente usare reflect per creare un oggetto di un tipo particolare nel modo in cui descrivi. Puoi usare reflect per vedere * if * un oggetto è di un particolare tipo ma non per costruire un tipo arbitrario. –

Problemi correlati