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!