구조체를 익명 클로저로 포함하는 것은 JSON에 추가 필드를 추가하는 일반적인 접근 방식입니다. 출력. 그러나 이 기술은 구조체 유형이 알려진 상황으로 제한됩니다.
임의의 구조체나 인터페이스를 처리할 때 기존 삽입 접근 방식은 실패합니다. 다음 코드를 고려하십시오.
type example interface{} type Data struct { Name string } type Extra struct { Text string } func printInterface(val interface{}) { example1 := struct { example Extra string }{ example: val, Extra: "text", } json.NewEncoder(os.Stdout).Encode(example1) } func main() { d := Data{Name:"name"} printInterface(&d) }
이 코드는 다음 JSON 출력을 생성합니다.
{"example":{"Name":"name"},"Extra":"text"}
보시다시피 Data 구조체의 Name 필드는 JSON 출력에 포함되지 않습니다. . 이는 인터페이스에 필드가 없으므로 기본 구조체의 필드가 승격되지 않기 때문입니다.
한 가지 해결책은 리플렉션을 사용하여 새 구조체 유형을 동적으로 생성하는 것입니다. . 이 구조체에는 알 수 없는 유형의 익명 필드와 추가 데이터를 위한 추가 필드가 포함됩니다.
func printInterface(val interface{}) { t2 := reflect.StructOf([]reflect.StructField{ reflect.StructField{ Name: "X", Anonymous: true, Type: reflect.TypeOf(val), }, reflect.StructField{ Name: "Extra", Type: reflect.TypeOf(""), }, }) v2 := reflect.New(t2).Elem() v2.Field(0).Set(reflect.ValueOf(val)) v2.FieldByName("Extra").SetString("text") json.NewEncoder(os.Stdout).Encode(v2.Interface()) }
이 코드는 원하는 JSON 출력을 생성합니다.
{"Name":"name","Extra":"text"}
또 다른 대안은 알 수 없는 값을 마샬링하고 이를 맵으로 역마샬링한 다음 추가 필드를 추가하고 맵을 다시 맵으로 마샬링하는 것입니다. JSON.
func printInterface(val interface{}) error { data, err := json.Marshal(val) if err != nil { return err } v2 := map[string]interface{}{} if err := json.Unmarshal(data, &v2); err != nil { return err } v2["Extra"] = "text" return json.NewEncoder(os.Stdout).Encode(v2) }
이 솔루션은 더 간단하지만 이중 마샬링 프로세스로 인해 효율성이 떨어질 수 있습니다.
위 내용은 Go에서 알 수 없는 구조체의 JSON 출력에 임의 필드를 추가하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!