Maison >développement back-end >Golang >Comment puis-je éliminer efficacement les champs JSON incohérents qui sont parfois des chaînes et parfois des tableaux de chaînes dans Go ?
Gestion des champs JSON incohérents : démarshalisation sous forme de chaîne ou de tableau
Lorsque vous travaillez avec des données JSON qui présentent des incohérences, il peut être difficile de décomplexer des champs dont le type peut varier, par exemple s'il s'agit d'une chaîne ou d'un tableau de chaînes. Cet article aborde ce problème et propose des solutions pratiques.
Le problème
Considérez la structure JSON suivante où le champ "display_name" est soit une chaîne, soit un tableau de chaînes. :
{ "date": "30 Apr", "display_name": "Mr Smith" }, { "date": "30 Apr", "display_name": ["Mr Smith", "Mr Jones"], }
Tenter de désorganiser ces données avec les structures Go suivantes entraînera un error :
type MyListItem struct { Date string `json:"date"` DisplayName string `json:"display_name"` } type MyListings struct { CLItems []MyListItem `json:"myitems"` }
Solution
Pour surmonter ce défi, on peut utiliser la polyvalence de json.RawMessage, qui permet la capture de différentes données de terrain. De plus, le nom du champ "-" peut être utilisé pour masquer le champ "DisplayName" du décodeur, permettant ainsi à l'application de le remplir une fois le JSON de niveau supérieur décodé.
Structure Go modifiée
type MyListItem struct { Date string `json:"date"` RawDisplayName json.RawMessage `json:"display_name"` DisplayName []string `json:"-"` }
Démarshalage Processus
Désorganisation du JSON de niveau supérieur :
var li MyListItem if err := json.Unmarshal(data, &li); err != nil { // handle error }
Reconstruction du champ "display_name" en fonction du type de données brutes :
if len(li.RawDisplayName) > 0 { switch li.RawDisplayName[0] { case '"': if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil { // handle error } case '[': var s []string if err := json.Unmarshal(li.RawDisplayName, &s); err != nil { // handle error } // Join arrays with "&&" per OP's comment on the question. li.DisplayName = strings.Join(s, "&&") } }
Pour plusieurs occurrences de ce champ incohérent dans un modèle de données, un type personnalisé et une implémentation de l'interface json.Unmarshaler peuvent être utilisés pour encapsuler la logique.
Unmarshaler personnalisé
type multiString string func (ms *multiString) UnmarshalJSON(data []byte) error { if len(data) > 0 { switch data[0] { case '"': var s string if err := json.Unmarshal(data, &s); err != nil { return err } *ms = multiString(s) case '[': var s []string if err := json.Unmarshal(data, &s); err != nil { return err } *ms = multiString(strings.Join(s, "&&")) } } return nil }
Utilisation avec Unmarshaler personnalisé
type MyListItem struct { Date string `json:"date"` DisplayName multiString `json:"display_name"` } type MyListings struct { CLItems []MyListItem `json:"myitems"` } var listings MyListings if err := json.Unmarshal([]byte(data), &listings); err != nil { log.Fatal(err) }
Ces solutions fournissent un approche complète pour gérer efficacement les champs JSON incohérents, permettant un mappage flexible entre les structures de données et JSON représentations.
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!