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