Maison > développement back-end > Golang > Comment puis-je conserver les types de données lors de l'analyse de JSON dans Go ?

Comment puis-je conserver les types de données lors de l'analyse de JSON dans Go ?

DDD
Libérer: 2024-11-25 02:46:10
original
729 Les gens l'ont consulté

How Can I Preserve Data Types When Parsing JSON in Go?

Préservation des types de données dans l'analyse JSON

Un défi rencontré lors de l'analyse des données JSON dans Golang est la conversion automatique des valeurs numériques en flottants. Cela peut entraîner des incohérences avec les données d'origine, en particulier lorsqu'il s'agit de valeurs entières.

Pour résoudre ce problème, il existe plusieurs techniques permettant de préserver les types de données lors de l'analyse JSON.

Personnalisé Valeurs JSON

Une approche consiste à utiliser le mécanisme de valeur JSON personnalisé fourni par Go. Cela implique la création d'un type personnalisé qui implémente les interfaces json.Marshaler et json.Unmarshaler. En remplaçant les méthodes MarshalJSON et UnmarshalJSON, vous pouvez contrôler la manière dont les valeurs numériques sont traitées lors de la sérialisation et de la désérialisation.

Allez json.Number

Une autre option consiste à utiliser le json .Type de numéro introduit dans Go 1.8. Par défaut, les valeurs numériques en JSON sont analysées comme float64. Cependant, en utilisant json.Number et en appelant les méthodes Int64 ou Float64, vous pouvez convertir explicitement le nombre en valeur entière ou en valeur à virgule flottante, respectivement.

Exemple d'implémentation

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
    "strings"
)

type MyJSONNumber struct {
    json.Number
}

func (mn *MyJSONNumber) MarshalJSON() ([]byte, error) {
    if n, err := strconv.Atoi(string(mn.Number)); err == nil {
        return []byte(strconv.Itoa(n)), nil
    }
    return []byte(mn.Number), nil
}

func (mn *MyJSONNumber) UnmarshalJSON(b []byte) error {
    if n, err := strconv.Atoi(string(b)); err == nil {
        mn.Number = strconv.Itoa(n)
        return nil
    }
    mn.Number = string(b)
    return nil
}

func main() {
    str := `{"a":123,"b":12.3,"c":"123","d":"12.3","e":true}`
    var raw map[string]json.RawMessage
    err := json.Unmarshal([]byte(str), &raw)
    if err != nil {
        panic(err)
    }
    parsed := make(map[string]interface{}, len(raw))
    for key, val := range raw {
        s := string(val)
        jnum := MyJSONNumber{json.Number(s)}
        n, err := jnum.Int64()
        if err == nil {
            parsed[key] = n
            continue
        }
        f, err := jnum.Float64()
        if err == nil {
            parsed[key] = f
            continue
        }
        var v interface{}
        err = json.Unmarshal(val, &v)
        if err == nil {
            parsed[key] = v
            continue
        }
        parsed[key] = val
    }
    for key, val := range parsed {
        fmt.Printf("%T: %v %v\n", val, key, val)
    }
}
Copier après la connexion

Sortie :

int64: a 123
float64: b 12.3
string: c 123
string: d 12.3
bool: e true
Copier après la connexion

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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal