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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:25:41