Maison >développement back-end >Golang >Comment puis-je analyser avec précision les entiers et les flottants à partir de JSON dans Golang ?

Comment puis-je analyser avec précision les entiers et les flottants à partir de JSON dans Golang ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-24 09:12:10424parcourir

How Can I Parse Integers and Floats Accurately from JSON in Golang?

Analyse d'entiers en tant qu'entiers et de flottants en tant que flottants en JSON à l'aide de Golang

Dans une application Golang qui reçoit un flux d'enregistrements JSON à transférer vers un magasin de données (InfluxDB), il est crucial de conserver le type de données d'origine des valeurs entières et flottantes pour éviter les conflits de types et garantir opérations d'écriture réussies. Alors que l'analyseur Ruby JSON effectue cette tâche sans effort, le package encoding/json de Golang analyse initialement tous les nombres sous forme de flottants, ce qui peut entraîner une incompatibilité de type et des échecs d'écriture.

Une solution de contournement utilisant des valeurs JSON personnalisées

Pour reproduire le comportement de l'analyseur Ruby JSON, une approche consiste à utiliser le mécanisme Go générique pour les valeurs JSON personnalisées. Dans cette méthode, les nombres JSON sont représentés sous forme de tableaux d'octets (json.RawMessage) et analysés à l'aide de strconv.ParseInt et strconv.ParseFloat. Cela permet une conversion précise des entiers et des flottants :

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

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)
        i, err := strconv.ParseInt(s, 10, 64)
        if err == nil {
            parsed[key] = i
            continue
        }
        f, err := strconv.ParseFloat(s, 64)
        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)
    }
}

Sortie :

int64: a 123 
float64: b 12.3 
string: c 123 
string: d 12.3 
bool: e true 

Utilisation du type json.Number

Une approche alternative consiste à utiliser le type Go json.Number, qui permet une analyse efficace des deux entiers. et flotte directement à partir des données JSON :

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

func main() {
    str := `{"a":123,"b":12.3,"c":"123","d":"12.3","e":true}`
    var parsed map[string]interface{}
    d := json.NewDecoder(strings.NewReader(str))
    d.UseNumber()
    err := d.Decode(&parsed)
    if err != nil {
        panic(err)
    }
    for key, val := range parsed {
        n, ok := val.(json.Number)
        if !ok {
            continue
        }
        if i, err := n.Int64(); err == nil {
            parsed[key] = i
            continue
        }
        if f, err := n.Float64(); err == nil {
            parsed[key] = f
            continue
        }
    }
    for key, val := range parsed {
        fmt.Printf("%T: %v %v\n", val, key, val)
    }
}

Sortie :

int64: a 123
float64: b 12.3
string: c 123
string: d 12.3
bool: e true

Ces méthodes fournissent des solutions efficaces pour préserver le type de données d'origine des entiers et des flottants pendant Analyse JSON dans Golang, garantissant une gestion précise et fiable des données.

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