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) } }
Sortie :
int64: a 123 float64: b 12.3 string: c 123 string: d 12.3 bool: e true
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!