Go通过反射创建struct实例赋值后JSON序列化值为空问题求解
问题根源
你的代码核心错误出在最后序列化的步骤:reflect.New(iFaceType)返回的item是reflect.Value类型的反射对象,不是实际的Person/*Person实例,你直接将反射对象传入json.Marshal,序列化库无法识别反射对象内部存储的字段值,就会返回空结果。
你已经正确通过反射给结构体字段赋值了,赋值逻辑本身没有问题,不需要改动。
修复方法
只需要修改序列化的调用语句,调用reflect.Value的Interface()方法提取出实际的实例对象即可:
// 原来的错误写法 fmt.Println("reflected: \n" + JSONify(item)) // 修改为 fmt.Println("reflected: \n" + JSONify(item.Interface()))
修改后运行即可得到正常的序列化结果,结构体原有的json、xml标签会完全保留,不影响序列化格式。
批量生成实例加入切片的实现示例
如果需要批量生成实例存入切片,可以参考如下通用逻辑:
// 假设要生成count个实例 count := 10 // 先推导切片类型 sliceType := reflect.SliceOf(iFaceType) // 创建新切片 slice := reflect.MakeSlice(sliceType, 0, count) for i := 0; i < count; i++ { // 新建结构体实例 item := reflect.New(iFaceType).Elem() // 字段赋值逻辑和你之前写的一致 item.FieldByName("Name").SetString(fmt.Sprintf("user_%d", i)) item.FieldByName("Age").SetInt(int64(20 + i)) // 加入切片 slice = reflect.Append(slice, item) } // 提取实际切片对象序列化 resultSlice := slice.Interface() fmt.Println(JSONify(resultSlice))
修改后可运行的完整代码
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() && fName.CanSet() && fName.Kind() == reflect.String { fName.SetString("reflectedNameValue") fmt.Println("Name was set to reflectedNameValue") } fAge := s.FieldByName("Age") if fAge.IsValid() && fAge.CanSet() && fAge.Kind() == reflect.Int { x := int64(42) if !fAge.OverflowInt(x) { fAge.SetInt(x) fmt.Println("Age was set to", x) } } } // 仅修改了这一行,调用Interface()提取实际实例 fmt.Println("reflected: \n" + JSONify(item.Interface())) } func JSONify(v interface{}) string { var bytes []byte bytes, _ = json.MarshalIndent(v, "", "\t") return string(bytes) }
内容的提问来源于stack exchange,提问作者lumo
相关产品推荐
相关产品推荐

