You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:36:06