Go에서 익명 구조체 필드는 일반적으로 내부 내보낸 필드가 외부 구조체의 필드인 것처럼 마샬링됩니다. 그러나 이로 인해 인터페이스{} 유형의 익명 멤버로 구조체를 마샬링할 때 예기치 않은 동작이 발생할 수 있습니다.
다음 예를 고려하세요.
<code class="go">type User struct { Id int `json:"id"` Name string `json:"name"` } type Session struct { Id int `json:"id"` UserId int `json:"userId"` } 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, "", " ") } func main() { u := &User{123, "James Dean"} s := &Session{456, 123} json, err := MarshalHateoas(u) if err != nil { panic(err) } else { fmt.Println("User JSON:") fmt.Println(string(json)) } json, err = MarshalHateoas(s) if err != nil { panic(err) } else { fmt.Println("Session JSON:") fmt.Println(string(json)) } }</code>
실행할 때 이 코드의 결과 JSON은 예상과 다릅니다.
<code class="json">User JSON: { "Anything": { "id": 123, "name": "James Dean" }, "_links": { "self": "http://user/123" } } Session JSON: { "Anything": { "id": 456, "userId": 123 }, "_links": { "self": "http://session/456" } }</code>
보시다시피 익명 멤버 Anything은 JSON에서 명명된 필드로 처리되는데 이는 의도한 동작이 아닙니다.
익명 멤버를 평면화하고 원하는 JSON 구조를 얻으려면 Reflect 패키지를 사용하여 구조체의 필드를 반복하고 이를 map[string]인터페이스{}에 매핑할 수 있습니다. 이를 통해 새 필드를 도입하지 않고도 원래 구조체의 평면 구조를 유지할 수 있습니다.
업데이트된 코드는 다음과 같습니다.
<code class="go">import ( "encoding/json" "fmt" "reflect" ) // ... (rest of the code remains the same) 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이 올바르게 평면화됩니다.
<code class="json">User JSON: { "id": 123, "name": "James Dean", "_links": { "self": "http://user/123" } } Session JSON: { "id": 456, "userId": 123, "_links": { "self": "http://session/456" } }</code>
위 내용은 Go JSON 직렬화에서 익명 인터페이스 필드를 평면화하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!