[英]Dynamically create struct of some type and unmarshal JSON into that instance
I am creating a struct instance at runtime. 我在运行时创建一个struct实例。 The instance has been created successfully, but I can't unmarshal JSON into it. 该实例已成功创建,但我无法将JSON解组到其中。
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()
. reflect.Indirect()
返回一个reflect.Value
类型的值,你应该将指向Test
(其类型为*Test
)的指针传递给json.Unmarshal()
。
Simply use the Value.Interface()
method to obtain the pointer to your Test
struct returned by reflect.New()
, like this: 只需使用Value.Interface()
方法获取指向reflect.New()
返回的Test
结构的指针,如下所示:
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. 注意f
将是interface{}
类型,保持*Test
指针值。 If you need the struct value, you may use type assertion, like this: 如果需要struct值,可以使用类型断言,如下所示:
t := *f.(*Test)
fmt.Println(t)
This prints: 这打印:
{go}
Try the examples on the Go Playground . 试试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
. 代码reflect.Indirect(reflect.New(elType))
返回一个reflect.Value
代替的具体值elType
。 And when you unmarshal it, the json package looks into the reflect.Value
struct which has no field Name
, so it does nothing. 当你解组它时,json包会查看没有字段Name
的reflect.Value
结构,所以它什么都不做。
Instead, you should use reflect.Value.Interface()
to turn it into an interface{}
holding the concrete type. 相反,您应该使用reflect.Value.Interface()
将其转换为保持具体类型的interface{}
。
Playground: https://play.golang.org/p/sW9mJd8fKMb 游乐场: https : //play.golang.org/p/sW9mJd8fKMb
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.