Go语言:如何将含嵌入结构体的CompleteStruct转指定JSON格式
解决方案:利用反射实现通用结构体转指定JSON数组
要处理这种包含多个嵌入结构体的批量转换需求,Go的反射机制是最优的通用方案,无需逐个字段硬编码。以下是完整实现:
1. 定义目标结构
先定义对应JSON数组元素的结构体,用来承载每个字段的元信息:
type FieldEntry struct { Name string `json:"name"` Field string `json:"field"` Value any `json:"value"` }
2. 实现反射转换函数
编写通用转换函数,遍历CompleteStruct的嵌入结构体,提取JSON标签与对应值,生成目标数组:
import ( "reflect" ) func ConvertToFieldEntries(s CompleteStruct) ([]FieldEntry, error) { entries := []FieldEntry{} name := s.Name // 获取结构体的反射值与类型 val := reflect.ValueOf(s) typ := val.Type() // 遍历外层结构体所有字段 for i := 0; i < typ.NumField(); i++ { fieldType := typ.Field(i) fieldVal := val.Field(i) // 跳过已单独处理的Name字段 if fieldType.Name == "Name" { continue } // 识别嵌入的匿名结构体 if fieldType.Anonymous && fieldVal.Kind() == reflect.Struct { // 遍历嵌入结构体的所有字段 embedTyp := fieldVal.Type() for j := 0; j < embedTyp.NumField(); j++ { embedFieldType := embedTyp.Field(j) embedFieldVal := fieldVal.Field(j) // 提取JSON标签,忽略无标签或标记为"-"的字段 jsonTag := embedFieldType.Tag.Get("json") if jsonTag == "" || jsonTag == "-" { continue } // 生成条目并加入数组 entries = append(entries, FieldEntry{ Name: name, Field: jsonTag, Value: embedFieldVal.Interface(), }) } } } return entries, nil }
3. 转换为目标JSON
使用标准库encoding/json将生成的条目数组转为格式化JSON:
import "encoding/json" func main() { s := CompleteStruct{ Name: "Example", StructA: StructA{ A: 1, B: 2, C: 3, }, StructB: StructB{ A: 4, B: 5, }, } entries, err := ConvertToFieldEntries(s) if err != nil { panic(err) } jsonData, err := json.MarshalIndent(entries, "", " ") if err != nil { panic(err) } println(string(jsonData)) }
关键细节说明
- 嵌入结构体识别:通过字段的
Anonymous属性判断是否为嵌入匿名结构体,同时校验字段类型为Struct。 - 标签提取逻辑:仅保留带有有效JSON标签的字段,可根据需求调整是否忽略无标签字段。
- 类型兼容性:用
any(即interface{})承载字段值,兼容int、string等基础数据类型。 - 扩展性:后续新增嵌入结构体或字段时,无需修改转换函数,自动适配。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

