Maison > développement back-end > Golang > Comment ajouter des champs arbitraires à la sortie JSON d'une structure inconnue dans Go ?

Comment ajouter des champs arbitraires à la sortie JSON d'une structure inconnue dans Go ?

Linda Hamilton
Libérer: 2024-12-29 17:47:10
original
431 Les gens l'ont consulté

How to Add Arbitrary Fields to the JSON Output of an Unknown Struct in Go?

Ajout de champs arbitraires à la sortie JSON d'une structure inconnue

Introduction

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.

Le problème : intégration de types inconnus

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

Ce code produit la sortie JSON suivante :

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

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.

Générer dynamiquement un type de structure

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

Ce code produit la sortie JSON souhaitée :

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

Marshaling Twice

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

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!

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