首页  >  文章  >  后端开发  >  如何使用匿名成员扁平化 Go 中的编组 JSON 结构?

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

Susan Sarandon
Susan Sarandon原创
2024-11-02 18:21:30414浏览

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn