2013-08-17 10 views
5

Here is the codeunmarshal na odzwierciedlenie wartości

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) 

} 

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

jestem w stanie unmarshal JSON do bazowego typu obiektu.

Co jest nie tak? Tak tu utknąłem. Coś bardzo prostego, ale trudnego do wymyślenia.

Dzięki

UPDATE :: Cel tego problemu jest retreive w pełni uformowany obiekt typu przekazany w funkcji GET.

Podejście, o którym wspomniał Nick w komentarzu poniżej, nie dostarcza mi faktycznego obiektu, którego wcześniej próbowałem. Mogę jakikolwiek pobierania danych (nawet wtedy, gdy obiekt ma rekurencyjne obiekty pod spodem) w mapie jak ten

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

Jednak muszę rzeczywisty obiekt z powrotem nie tylko dane. Coś takiego jak user := &User{"SomeName"}, gdzie potrzebuję obiektu z powrotem z Unmarshall. Sztuczka jest gdzieś w odbiciu, ale nie wiem jak.

+0

Reflect nie zrobi tego, o czym myślisz, że tak będzie. Nie możesz skonstruować dowolnego obiektu za jego pomocą. Prawdopodobnie mógłbyś coś połączyć ze sobą za pomocą odbicia i niebezpieczeństwa, ale naprawdę powinieneś przemyśleć to, co próbujesz zrobić. –

+0

Dzięki, zamykam ten wątek. Dzięki za poświęcenie czasu. Daje +1 Twoim odpowiedziom. – Minty

Odpowiedz

3

Jestem zdezorientowany, dlaczego chcesz to zrobić, ale tutaj jest to, jak go naprawić

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

uwaga wezwanie do Interface().

Playground link

Wydaje mi się, że masz zamiar dużo trudu, aby pusty &User gdy masz już jedną w b, np

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

Ale zgaduję istnieje trochę więcej do tego planu, którego tu nie widać!

+0

Dzięki, ale już wypróbowałem tę sztuczkę.Są z tym dwa problemy. – Minty

+0

1. Nie będzie działać na rekursywnych typach obiektów. To jest obiekt wewnątrz obiektu i 2. Zwrócone dane nie są obiektem typu wysłanego w Get funtion. To trudna część. Zaktualizowałem moje pytanie, aby to wyjaśnić. – Minty

+0

Co zwrócił obiekt? Nie zwracasz obiektu. b, który jest już właściwym typem, zostaje zapełniony przez wywołanie MustJSONDecode. –

1

reflect.New(objType) zwraca reflect.Value Co nie jest tak, jak interfejs, który minął. Według dokumentów dla Value Jest to struktura z tylko nieodportowanymi polami. pakiet json nie może działać z nieodportowanymi polami. Ponieważ nie jest to ten sam obiekt, który przekazałeś i nie jest nawet kodowany/dekodowalny przez Json, pakiet json zawiedzie.

Prawdopodobnie artykuł Laws of Reflection będzie przydatny podczas próby użycia pakietu reflect.

+0

Dzięki za referencję. Przeczytałem to trzy razy, ale wydaje mi się, że zauważyłem, że ten artykuł (który jest bardzo intymny) nie mówi o tworzeniu obiektów z innych obiektów. Być może, gdyby autor utrzymał to jako część dyskrecji programisty. – Minty

+1

Nie można tak naprawdę użyć odbicia, aby utworzyć obiekt określonego typu w sposób opisany przez użytkownika. Możesz użyć funkcji reflect, aby zobaczyć *, jeśli * obiekt jest określonego typu, ale nie może tworzyć dowolnego typu. –

Powiązane problemy