Maison > développement back-end > Golang > Comment ajouter dynamiquement des champs à la sortie JSON à partir de structures Go inconnues ?

Comment ajouter dynamiquement des champs à la sortie JSON à partir de structures Go inconnues ?

Mary-Kate Olsen
Libérer: 2024-12-04 15:31:12
original
715 Les gens l'ont consulté

How to Dynamically Add Fields to JSON Output from Unknown Go Structs?

Amélioration dynamique de la sortie JSON de structures inconnues

Introduction
Dans Go, il est possible d'améliorer la Sortie JSON des structures connues en les intégrant sous forme de champs anonymes. Cependant, cette technique ne fonctionne qu’avec des types spécifiques. Cet article explore comment étendre cette fonctionnalité à des structures ou des interfaces inconnues.

Exemple
Considérez l'exemple suivant :

type example interface{}
type Data struct {
    Name 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)
}
Copier après la connexion

Ce code imprime le JSON suivant :

{"example":{"Name":"name"},"Extra":"text"}
Copier après la connexion

Remarquez comment le champ "Nom" est enveloppé dans un "exemple" inutile object.

Solution 1 : Générer des types dynamiques avec réflexion
Pour éviter l'objet "exemple", nous devons générer un type dynamique au moment de l'exécution. Nous pouvons utiliser la réflexion pour créer un type de structure qui intègre l'interface inconnue et inclut notre champ "Extra" supplémentaire.

func printInterface(val interface{}) {
    t2 := reflect.StructOf([]reflect.StructField{
        {
            Name:      "X",
            Anonymous: true,
            Type:      reflect.TypeOf(val),
        },
        {
            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())
}
Copier après la connexion

Avec ce changement, le résultat devient :

{"Name":"name","Extra":"text"}
Copier après la connexion

Solution 2 : Marshaling et Unmarshalling
Une approche alternative consiste à rassembler l'interface, à la désorganiser dans une carte, ajoutez le champ supplémentaire, puis rassemblez à nouveau :

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)
}
Copier après la connexion

Cette méthode produit le même résultat que l'approche de type dynamique.

Conclusion
Les deux solutions présentées activez ici l'extension de la sortie JSON avec des champs arbitraires pour les structures ou interfaces inconnues. L'approche basée sur la réflexion fournit une solution de type sécurisé, tandis que la technique de marshaling et de démarshaling est plus simple mais potentiellement plus lente. Le choix de la méthode dépend des exigences spécifiques de l'application.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal