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
Linda Hamiltonoriginal
2024-12-29 17:47:10466parcourir

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)
}

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.

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())
}

Ce code produit la sortie JSON souhaitée :

{"Name":"name","Extra":"text"}

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)
}

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!

Déclaration:
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