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 タグ名を抽出して、それらをフラット化されたマップ[文字列]インターフェイス{}にマッピングします。リフレクションを使用することで、新しい名前付きフィールドの追加を回避し、元のフラットな構造を保持します。
このソリューションの使用方法の例を次に示します。
<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>
Withこの改善された MarshalHateoas 関数により、サンプルの JSON 出力は次のようになります。
<code class="json">{ "id": 123, "name": "James Dean", "_links": { "self": "http://user/123" } }</code>
リフレクションを活用することで、匿名メンバーを含む JSON 構造体を効果的にフラット化し、データの整合性を損なうことなく目的の JSON 構造を実現できます。 。このソリューションは、Go で複雑な JSON シリアル化シナリオを処理するための堅牢な方法を提供します。
以上がGo で匿名メンバーを使用してマーシャリングされた JSON 構造体をフラット化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。