이렇게하려면 두 가지 방법이 있지만 가장 쉬운 방법은 페이로드를 두 번 deserialize하고 페이로드의 "AnimalType"특성을 기반으로 조건 분기를하는 것입니다. 여기에 중간 역 직렬화 모델을 사용하여 간단한 예입니다
package main
import (
"fmt"
"encoding/json"
)
type Dog struct {
AnimalType string //will always be "dog"
BarkLoudnessLevel int
}
type Cat struct {
AnimalType string //will always be "cat"
SleepsAtNight bool
}
var (
payloadOne = `{"AnimalType":"dog","BarkLoudnessLevel":1}`
payloadTwo = `{"AnimalType":"cat","SleepsAtNight":false}`
)
func main() {
parseAnimal(payloadOne)
parseAnimal(payloadTwo)
}
func parseAnimal(payload string) {
animal := struct{
AnimalType string
}{}
if err := json.Unmarshal([]byte(payload), &animal); err != nil {
panic(err)
}
switch animal.AnimalType {
case "dog":
dog := Dog{}
if err := json.Unmarshal([]byte(payload), &dog); err != nil {
panic(err)
}
fmt.Printf("Got a dog: %v\n", dog)
case "cat":
cat := Cat{}
if err := json.Unmarshal([]byte(payload), &cat); err != nil {
panic(err)
}
fmt.Printf("Got a cat: %v\n", cat)
default:
fmt.Println("Unknown animal")
}
}
행동 here에서를 참조하십시오.
IMO이 예상되는 JSON 페이로드를 수정 필요하지만이 부모 구조로 페이로드에 대한 "메타 데이터"이동 접근하는 더 좋은 방법. 따라서, 예를 들어, 당신처럼 보였다 페이로드와 함께 작업하는 경우 :
{"AnimalType":"dog", "Animal":{"BarkLoudnessLevel": 1}}
이 그럼 당신은 부분적으로 구조를 분석 할 json.RawMessage
같은 것을 사용할 수 있습니다 및 다음 필요에 따라 조건부로 나머지 구문 분석 (오히려 모든 것을 분석하는 것보다 두 배) - 또한 구조 속성을 더 잘 분리합니다. 다음과 같은 예가 있습니다.
package main
import (
"encoding/json"
"fmt"
)
type Animal struct {
AnimalType string
Animal json.RawMessage
}
type Dog struct {
BarkLoudnessLevel int
}
type Cat struct {
SleepsAtNight bool
}
var (
payloadOne = `{"AnimalType":"dog", "Animal":{"BarkLoudnessLevel": 1}}`
payloadTwo = `{"AnimalType":"cat", "Animal":{"SleepsAtNight": false}}`
)
func main() {
parseAnimal(payloadOne)
parseAnimal(payloadTwo)
}
func parseAnimal(payload string) {
animal := &Animal{}
if err := json.Unmarshal([]byte(payload), &animal); err != nil {
panic(err)
}
switch animal.AnimalType {
case "dog":
dog := Dog{}
if err := json.Unmarshal(animal.Animal, &dog); err != nil {
panic(err)
}
fmt.Printf("Got a dog: %v\n", dog)
case "cat":
cat := Cat{}
if err := json.Unmarshal(animal.Animal, &cat); err != nil {
panic(err)
}
fmt.Printf("Got a cat: %v\n", cat)
default:
fmt.Println("Unknown animal")
}
}
그리고 동작이 here입니다.
이동 웹 사이트 (https://golang.org/pkg/encoding/json/)에서 제공되는 예제를 살펴 보겠습니다. "Example (CustomMarshalJSON)"을 참조하십시오. –
"예제 (Unmarshal) "['json.RawMessage' 유형] (https://golang.org/pkg/encoding/json/#RawMessage)을 참조하십시오. – maerics