Maison >développement back-end >Golang >Comment décoder et mettre à jour partiellement des objets JSON dans Go ?

Comment décoder et mettre à jour partiellement des objets JSON dans Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-25 00:29:16855parcourir

How to Partially Decode and Update JSON Objects in Go?

Décodage et mise à jour JSON partiel dans Go

Dans certains scénarios, un problème courant survient lors du décodage et de la mise à jour uniquement des valeurs spécifiques d'un objet JSON , surtout lorsque la structure complète de l'objet est inconnue. Le package encoding/json standard dans Go tronque les champs non fournis dans la structure, entraînant une perte de données.

Solution utilisant json.RawMessage

Une solution à ce problème est pour combiner une structure personnalisée avec json.RawMessage. Cette approche nous permet de conserver l'intégralité des données dans un champ brut pour l'encodage/décodage.

Le type json.RawMessage dans Go est une valeur []byte qui peut contenir des données JSON arbitraires. C'est utile dans des cas comme celui-ci, où nous ne connaissons qu'une partie de la structure JSON et souhaitons conserver les parties inconnues.

Exemple de code

package main

import (
    "encoding/json"
    "log"
)

type Color struct {
    Space string
    raw   map[string]json.RawMessage
}

func (c *Color) UnmarshalJSON(bytes []byte) error {
    if err := json.Unmarshal(bytes, &c.raw); err != nil {
        return err
    }
    if space, ok := c.raw["Space"]; ok {
        if err := json.Unmarshal(space, &c.Space); err != nil {
            return err
        }
    }
    return nil
}

func (c *Color) MarshalJSON() ([]byte, error) {
    bytes, err := json.Marshal(c.Space)
    if err != nil {
        return nil, err
    }
    c.raw["Space"] = json.RawMessage(bytes)
    return json.Marshal(c.raw)
}

func main() {
    before := []byte(`{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}`)
    log.Println("before: ", string(before))

    // decode
    color := new(Color)
    err := json.Unmarshal(before, color)
    if err != nil {
        log.Fatal(err)
    }

    // modify fields of interest
    color.Space = "RGB"

    // encode
    after, err := json.Marshal(color)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("after:  ", string(after))
}

Sortie

before:  {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}
after:   {"Point":{"Y":255,"Cb":0,"Cr":-10},"Space":"RGB"}

Cette solution nous permet de décoder et de mettre à jour uniquement une valeur spécifique (dans ce cas, l'Espace) tout en préservant toutes les autres données inconnues dans l'objet JSON. Il est important de noter que cette approche ne préserve pas l'ordre des clés ni les indentations dans la sortie.

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