首页 > 后端开发 > Golang > 如何动态地将字段添加到未知 Go 结构的 JSON 输出?

如何动态地将字段添加到未知 Go 结构的 JSON 输出?

Mary-Kate Olsen
发布: 2024-12-04 15:31:12
原创
725 人浏览过

How to Dynamically Add Fields to JSON Output from Unknown Go Structs?

动态增强未知结构的 JSON 输出

简介
在 Go 中,可以增强通过将已知结构嵌入为匿名字段来进行 JSON 输出。但是,此技术仅适用于特定类型。本文探讨如何将此功能扩展到未知的结构或接口。

示例
考虑以下示例:

type example interface{}
type Data struct {
    Name string
}

func printInterface(val interface{}) {
    example1 := struct {
        example
        Extra string
    }{
        example: val,
        Extra: "text",
    }
    json.NewEncoder(os.Stdout).Encode(example1)
}

func main() {
    d := Data{Name: "name"}
    printInterface(&d)
}
登录后复制

此代码打印以下 JSON :

{"example":{"Name":"name"},"Extra":"text"}
登录后复制

注意“名称”字段是如何包装在不必要的“示例”中的

解决方案1:通过反射生成动态类型
为了避免“示例”对象,我们需要在运行时生成动态类型。我们可以使用反射来创建一个嵌入未知接口并包含附加“Extra”字段的结构类型。

func printInterface(val interface{}) {
    t2 := reflect.StructOf([]reflect.StructField{
        {
            Name:      "X",
            Anonymous: true,
            Type:      reflect.TypeOf(val),
        },
        {
            Name: "Extra",
            Type: reflect.TypeOf(""),
        },
    })

    v2 := reflect.New(t2).Elem()
    v2.Field(0).Set(reflect.ValueOf(val))
    v2.FieldByName("Extra").SetString("text")

    json.NewEncoder(os.Stdout).Encode(v2.Interface())
}
登录后复制

通过此更改,输出将变为:

{"Name":"name","Extra":"text"}
登录后复制

解决方案 2:编组和解组
另一种方法是编组接口,将其解组到映射中,添加附加字段,然后再次编组:

func printInterface(val interface{}) error {
    data, err := json.Marshal(val)
    if err != nil {
        return err
    }

    v2 := map[string]interface{}{}
    if err := json.Unmarshal(data, &v2); err != nil {
        return err
    }

    v2["Extra"] = "text"
    return json.NewEncoder(os.Stdout).Encode(v2)
}
登录后复制

此方法产生与动态类型方法相同的输出。

结论
这里提出的两种解决方案都可以使用未知结构或接口的任意字段扩展 JSON 输出。基于反射的方法提供了类型安全的解决方案,而编组和解组技术更简单,但可能更慢。方法的选择取决于应用程序的具体要求。

以上是如何动态地将字段添加到未知 Go 结构的 JSON 输出?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板