I am creating a struct instance at runtime. The instance has been created successfully, but I can't unmarshal JSON into it.
type Test struct {
Name string `json:"name,omitempty"`
}
func create(a interface{}) {
aType := reflect.TypeOf(a).Elem()
elType := aType.Elem()
f := reflect.Indirect(reflect.New(elType))
b := []byte(`{"name": "go"}`)
err := json.Unmarshal(b, &f)
fmt.Println(err, f)
}
func main() {
l := []Test{}
create(&l)
}
reflect.Indirect()
returns you a value of type reflect.Value
, and you should pass a pointer to Test
(which is of type *Test
) to json.Unmarshal()
.
Simply use the Value.Interface()
method to obtain the pointer to your Test
struct returned by reflect.New()
, like this:
f := reflect.New(elType).Interface()
b := []byte(`{"name": "go"}`)
err := json.Unmarshal(b, f)
With this it works, and output will be:
<nil> &{go}
Note that f
will be of interface{}
type, holding the *Test
pointer value. If you need the struct value, you may use type assertion, like this:
t := *f.(*Test)
fmt.Println(t)
This prints:
{go}
Try the examples on the Go Playground .
I don't think you need to use reflect, instead you can do the following:
type Test struct {
Name string `json:"name,omitempty"`
}
func create(a interface{}) {
b := []byte(`[{"name": "go"}]`)
err := json.Unmarshal(b, &a)
fmt.Println(err, a)
}
func main() {
l := []Test{}
create(&l)
}
The code reflect.Indirect(reflect.New(elType))
returns a reflect.Value
instead of a concrete value of elType
. And when you unmarshal it, the json package looks into the reflect.Value
struct which has no field Name
, so it does nothing.
Instead, you should use reflect.Value.Interface()
to turn it into an interface{}
holding the concrete type.
Playground: https://play.golang.org/p/sW9mJd8fKMb
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.