在 Go 中編組 JSON 資料時,匿名成員可能會帶來意想不到的複雜性。本文深入研究了解決這些挑戰的解決方案。
考慮以下程式碼:
<code class="go">type Hateoas struct { Anything Links map[string]string `json:"_links"` }</code>
當Hateoas 包含匿名成員時,JSON 封送拆收器會處理它們作為常規命名字段,導致不需要的嵌套:
<code class="json">{ "Anything": { "id": 123, "name": "James Dean" }, "_links": { "self": "http://user/123" } }</code>
為了扁平化JSON 結構並消除額外的嵌套,我們可以利用反射:
<code class="go">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() }</code>
此循環迭代結構體的字段,提取它們的JSON 標籤名稱,並將它們映射到扁平化的map[string]interface{}。透過使用反射,我們避免添加新的命名欄位並保留原始的平面結構。
以下是如何使用此解決方案的範例:
<code class="go">import "reflect" 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>
與透過這個改良的MarshalHateoas 函數,範例JSON 輸出變成:
<code class="json">{ "id": 123, "name": "James Dean", "_links": { "self": "http://user/123" } }</code>
透過利用反射,我們可以有效地展平具有匿名成員的JSON 結構,並在不影響資料完整性的情況下實現所需的JSON 結構。該解決方案提供了一種強大的方法來處理 Go 中複雜的 JSON 序列化場景。
以上是如何在 Go 中使用匿名成員展平編組 JSON 結構?的詳細內容。更多資訊請關注PHP中文網其他相關文章!