L'intégration de structures en tant que fermetures anonymes est une approche courante pour ajouter des champs supplémentaires à JSON sorties. Cependant, cette technique est limitée aux situations où le type de structure est connu.
Lorsqu'il s'agit de structures ou d'interfaces arbitraires, l'approche d'intégration traditionnelle échoue. Considérez le code suivant :
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) }
Ce code produit la sortie JSON suivante :
{"example":{"Name":"name"},"Extra":"text"}
Comme vous pouvez le voir, le champ Nom de la structure Data n'est pas inclus dans la sortie JSON. . En effet, les interfaces n'ont pas de champs et donc les champs de la structure sous-jacente ne sont pas promus.
Une solution consiste à générer dynamiquement un nouveau type de structure à l'aide de la réflexion. . Cette structure contiendra un champ anonyme de type inconnu et un champ supplémentaire pour les données supplémentaires.
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()) }
Ce code produit la sortie JSON souhaitée :
{"Name":"name","Extra":"text"}
Une autre alternative consiste à rassembler la valeur inconnue, à la désorganiser dans une carte, à ajouter le champ supplémentaire et à réorganiser la carte dans 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) }
Cette solution est plus simple mais peut être moins efficace en raison du processus de double marshaling.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!