문제 설명
Go의 json.Unmarshal을 사용하여 문자열을 디코딩하는 경우 메시지 시스템에서 결과는 대신 map[string]interface{}인 것으로 나타났습니다. 예상되는 구조체 유형(Somthing1 또는 Somthing2)으로 인해 유형 어설션이 불가능해집니다.
근본 원인
인터페이스로 역정렬화할 때 json.Unmarshal 함수{}, 기본값은 []interface{} 및 map[string]interface{}와 같은 알려진 유형입니다. 주어진 코드에서 인터페이스 변수 입력은 마샬링되지 않은 JSON 데이터를 나타내는 map[string]interface{}를 수신하지만, switch 문은 이를 Somthing1 또는 Somthing2로 직접 주장하려고 시도합니다.
해결책
JSON은 기본적으로 원하는 구조체로 역마샬링되지 않으므로 이 문제를 해결하는 두 가지 옵션이 있습니다. 문제:
1. 일반 맵에서 검사 및 변환:
한 가지 접근 방식은 map[string]인터페이스{}를 검사하고 수동으로 데이터를 적절한 구조체 유형으로 압축을 푸는 것입니다. 그러나 이를 위해서는 잠재적인 오류를 주의 깊게 처리하고 값을 수동으로 할당해야 합니다.
2. 사용자 정의 JSON 언마샬러 활용:
더 깔끔한 솔루션은 언마샬링 프로세스를 처리하기 위해 사용자 정의 JSON 언마샬러를 생성하는 것입니다. 이 사용자 정의 역마샬러는 JSON 데이터를 기반으로 올바른 구조체 유형을 식별하고 그에 따라 역마샬링할 수 있습니다. 다음은 이러한 언마샬러의 예입니다.
type Unpacker struct { Data interface{} } func (u *Unpacker) UnmarshalJSON(b []byte) error { smth1 := &Something1{} err := json.Unmarshal(b, smth1) // no error, but we also need to make sure we unmarshaled something if err == nil && smth1.Thing != "" { u.Data = smth1 return nil } // abort if we have an error other than the wrong type if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok { return err } smth2 := &Something2{} err = json.Unmarshal(b, smth2) if err != nil { return err } u.Data = smth2 return nil }
이 사용자 정의 언마샬러의 인스턴스를 json.Unmarshal에 전달하면 결과 데이터 필드에 올바른 구조체 유형의 마샬링되지 않은 데이터가 포함되어 원활한 유형 어설션이 가능해집니다. .
위 내용은 Go의 `json.Unmarshal`을`interface{}`와 함께 사용할 때 JSON 데이터를 특정 구조체로 효율적으로 역마샬링하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!