Reputation: 1241
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 the Get function
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)
}
I am unable to unmarshal the json into the underlying object type.
Whats wrong here? I am so stuck here. Something very simple yet so difficult to figure out.
Thanks
UPDATE::Goal of this problem is to retreive a fully formed object of type passed in Get function.
The approach mentioned by Nick on the comment below doesnot get me the actual object which I already tried before. I can anyways retrieve the data (even when the object has recursive objects underneath) in a map like this
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)
}
However I need the actual object back not just the data. Something like user := &User{"SomeName"}
where I need user
object back from Unmarshall. The trick is somewhere in reflection but dont know how.
Upvotes: 5
Views: 7007
Reputation: 54089
I'm confused as to why you want to do this, but here is how to fix it
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)
}
Note the call to Interface().
It seems to me that you are going to a lot of trouble to make an empty &User
when you already have one in b
, eg
func Get(a []byte, b interface{}) {
MustJSONDecode(a, &b)
fmt.Printf("obj = %#v\n", b)
}
But I'm guessing there is some more to this plan which isn't apparent here!
Upvotes: 5
Reputation: 25237
reflect.New(objType)
returns a reflect.Value
Which is not the thing as the interface you passed. According to the docs for Value It is a struct with only unexported fields. the json package can't work with unexported fields. Since it's not the same object as you passed in and it's not even json encodable/decodable the json package will fail.
You will probably find the Laws of Reflection article useful while trying to use the reflect package.
Upvotes: 1