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

如何使用Go语言JEN包根据JSON动态为结构体添加字段

问题

如何使用Go语言的JEN包,根据JSON数据动态为结构体添加字段?

具体需求:遍历指定JSON中的yAxisColumn数组,提取每个对象的name字段,将其格式化为结构体字段并添加db、json标签,最终整合到结构体中。

预期代码生成结果:

var queryOutput [][]struct {
        product_name string `db:"product_name" json:"product_name"`
        category     string `db:"category" json:"category"`
        category2    string `db:"category2" json:"category2"`
    }

现有遍历JSON的代码片段:

for _, yaxis := range YAxisColumn {
        columns := yaxis.(map[string]interface{})
        columnName := columns["name"].(string)
        c:= jen.Id(utils.GetFormattedName(columnName)).Int().Tag(map[string]string{
            "json": GetFormattedName(columnName),
            "db":   GetFormattedName(columnName),
        }),
    }

待添加字段的结构体代码块:

return jen.Func().Id(serviceName).Params().Parens(
        jen.List(jen.Interface(), jen.Error()),
    ).Block(
        jen.Var().Id("queryOutput").Op("[][]").Struct(
            jen.Id(utils.GetFormattedName(XAxisColumn)).String().Tag(map[string]string{
                "json": utils.GetFormattedName(XAxisColumn),
                "db":   utils.GetFormattedName(XAxisColumn),
            }),
),

参考JSON数据:

"yAxisColumn" : [
    {
        "name": "category",
        "color": ""
    },
    {
        "name": "category2",
         "color":""
    }
],
解决方案

核心思路是先收集所有需要生成的结构体字段(包含X轴固定字段和Y轴动态字段),再将字段集合传入jen.Struct()方法完成动态构建。

1. 收集所有结构体字段

初始化切片存储字段,先添加X轴固定字段,再遍历Y轴数组生成动态字段并入切片:

// 初始化字段切片,先加入X轴固定字段
structFields := []jen.Code{
    jen.Id(utils.GetFormattedName(XAxisColumn)).String().Tag(map[string]string{
        "json": utils.GetFormattedName(XAxisColumn),
        "db":   utils.GetFormattedName(XAxisColumn),
    }),
}

// 遍历YAxisColumn生成动态字段
for _, yaxis := range YAxisColumn {
    columns := yaxis.(map[string]interface{})
    columnName := columns["name"].(string)
    formattedName := utils.GetFormattedName(columnName)
    // 生成string类型字段(与预期输出匹配,替换原代码的Int())
    field := jen.Id(formattedName).String().Tag(map[string]string{
        "json": formattedName,
        "db":   formattedName,
    })
    structFields = append(structFields, field)
}

2. 动态构建结构体

将收集好的字段切片以可变参数形式传入jen.Struct(),替换原有的单个字段:

return jen.Func().Id(serviceName).Params().Parens(
    jen.List(jen.Interface(), jen.Error()),
).Block(
    // 传入所有字段构建结构体
    jen.Var().Id("queryOutput").Op("[][]").Struct(structFields...),
    // 补充函数体其他逻辑(示例返回语句)
    jen.Return(jen.Nil(), jen.Nil()),
)

关键注意点

  • 原代码中动态字段使用Int()类型,与预期的string不符,需改为String()才能匹配输出要求。
  • 使用structFields...可变参数传递所有字段,实现结构体字段的动态添加。
  • 确保utils.GetFormattedName能正确将JSON中的name转换为符合Go规范的字段命名(如下划线风格)。

内容的提问来源于stack exchange,提问作者omkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:10:34