首页 > 后端开发 > Golang > 正文

如何使用匿名成员扁平化 Go 中的编组 JSON 结构?

Susan Sarandon
发布: 2024-11-02 18:21:30
原创
481 人浏览过

How to flatten Marshalled JSON Structs in Go with anonymous members?

在 Go 中使用匿名成员扁平化编组 JSON 结构

在以下代码中:

<code class="go">type Anything interface{}

type Hateoas struct {
    Anything
    Links map[string]string `json:"_links"`
}

func MarshalHateoas(subject interface{}) ([]byte, error) {
    h := &Hateoas{subject, make(map[string]string)}
    switch s := subject.(type) {
    case *User:
        h.Links["self"] = fmt.Sprintf("http://user/%d", s.Id)
    case *Session:
        h.Links["self"] = fmt.Sprintf("http://session/%d", s.Id)
    }
    return json.MarshalIndent(h, "", "    ")
}</code>
登录后复制

目标是以扁平化匿名成员的方式编组 JSON。默认情况下,匿名成员在 JSON 输出中被视为单独的命名字段。

解决方案是使用 Reflect 包手动将我们希望序列化的结构体的字段映射到映射[字符串]接口{}。通过这种方式,我们可以保留原始结构体的扁平结构,而无需引入新的字段。

这是完成此操作的代码:

<code class="go">func MarshalHateoas(subject interface{}) ([]byte, error) {
    links := make(map[string]string)
    out := make(map[string]interface{})
    subjectValue := reflect.Indirect(reflect.ValueOf(subject))
    subjectType := subjectValue.Type()
    for i := 0; i < subjectType.NumField(); i++ {
        field := subjectType.Field(i)
        name := subjectType.Field(i).Name
        out[field.Tag.Get("json")] = subjectValue.FieldByName(name).Interface()
    }
    switch s := subject.(type) {
    case *User:
        links["self"] = fmt.Sprintf("http://user/%d", s.Id)
    case *Session:
        links["self"] = fmt.Sprintf("http://session/%d", s.Id)
    }
    out["_links"] = links
    return json.MarshalIndent(out, "", "    ")
}</code>
登录后复制

此代码迭代结构体的字段,检索它们的值,并使用字段的 JSON 标记作为键将它们添加到输出映射中。此过程确保匿名成员的字段被平铺到输出映射中。

通过以这种方式自定义 JSON 编组过程,我们可以实现所需的 JSON 输出,同时保持接口提供的灵活性和类型安全性。

以上是如何使用匿名成员扁平化 Go 中的编组 JSON 结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

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