【发布时间】:2022-01-09 02:37:02
【问题描述】:
我想做什么
我尝试将instance 的struct 传递给tags,包括tags 到func,创建一个新的instance,并在field 上设置value
在此之后我尝试序列化(JSON),但值为空
注意:我在 SO 上查找了大量关于通过反射设置值的文章,但似乎我错过了一些细节
结构定义
这部分定义了带有 json 和 xml 标签的结构
type Person struct {
Name string `json:"Name" xml:"Person>FullName"`
Age int `json:"Age" xml:"Person>Age"`
}
创建实例(+包装成空接口)
之后我创建了一个实例并将其存储在 interface{} 中 - 为什么?因为在我的生产代码中,这些东西将在func 中完成,它接受interface{}
var iFace interface{} = Person{
Name: "Test",
Age: 666,
}
创建结构的新实例并通过反射设置值
iFaceType := reflect.TypeOf(iFace)
item := reflect.New(iFaceType)
s := item.Elem()
if s.Kind() == reflect.Struct {
fName := s.FieldByName("Name")
if fName.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fName.CanSet() {
// change value of N
switch fName.Kind() {
case reflect.String:
fName.SetString("reflectedNameValue")
fmt.Println("Name was set to reflectedNameValue")
}
}
}
fAge := s.FieldByName("Age")
if fAge.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fAge.CanSet() {
// change value of N
switch fAge.Kind() {
case reflect.Int:
x := int64(42)
if !fAge.OverflowInt(x) {
fAge.SetInt(x)
fmt.Println("Age was set to", x)
}
}
}
}
}
问题
我做错了什么?
在生产代码中,我用数据填充多个副本并将其添加到 slice...
但这只有在 json tags 保持在原位并且东西以相同的方式序列化时才有意义。
播放代码示例
package main
import (
"encoding/json"
"fmt"
"reflect"
)
func main() {
type Person struct {
Name string `json:"Name" xml:"Person>FullName"`
Age int `json:"Age" xml:"Person>Age"`
}
var iFace interface{} = Person{
Name: "Test",
Age: 666,
}
fmt.Println("normal: \n" + JSONify(iFace))
iFaceType := reflect.TypeOf(iFace)
item := reflect.New(iFaceType)
s := item.Elem()
if s.Kind() == reflect.Struct {
fName := s.FieldByName("Name")
if fName.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fName.CanSet() {
// change value of N
switch fName.Kind() {
case reflect.String:
fName.SetString("reflectedNameValue")
fmt.Println("Name was set to reflectedNameValue")
}
}
}
fAge := s.FieldByName("Age")
if fAge.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fAge.CanSet() {
// change value of N
switch fAge.Kind() {
case reflect.Int:
x := int64(42)
if !fAge.OverflowInt(x) {
fAge.SetInt(x)
fmt.Println("Age was set to", x)
}
}
}
}
}
fmt.Println("reflected: \n" + JSONify(item))
}
func JSONify(v interface{}) string {
var bytes []byte
bytes, _ = json.MarshalIndent(v, "", "\t")
return string(bytes)
}
【问题讨论】:
标签: json go struct reflection