Leçons du module (5/5)
encoding/json
encoding/json est le package canonique pour sérialiser les structures Go en JSON et vice versa. Connaître ses conventions et ses pièges vous évite des heures de débogage des API et des fichiers de configuration.
Maréchal et démaréchal
Les deux fonctions principales :
data, err := json.Marshal(v) // Go → []byte JSON
err = json.Unmarshal(data, &v) // JSON → Go (passa puntatore!)type User struct {
Name string
Email string
}
u := User{Name: "Ada", Email: "ada@example.com"}
b, _ := json.Marshal(u)
fmt.Println(string(b))
// {"Name":"Ada","Email":"ada@example.com"}
var back User
_ = json.Unmarshal(b, &back)Pour une sortie en retrait (lisible par l’homme), utilisez json.MarshalIndent(v, "", " ").
Champs exportés uniquement
json.Marshal sérialise les champs exportés uniquement (majuscules). Les champs privés sont ignorés en silence :
type U struct {
Name string // esportato → serializzato
age int // privato → ignorato
}Balise Struct : contrôle du nom et des options
Les balises json:"..." contrôlent le nom, l'omission et les types dans la sortie :
type User struct {
Name string `json:"name"` // rinomina
Email string `json:"email,omitempty"` // omette se zero value
Private string `json:"-"` // mai serializzato
ID int `json:"id,string"` // numero come stringa
}Options les plus utilisées :
,omitempty— omettez le champ s'il s'agit de la valeur zéro (0, "", nul, tranche/carte vide).,-— jamais sérialisé/désérialisé.,string— encapsule les nombres/booléens sous forme de chaînes (utile pour les identifiants JS).
Décodeur/Encodeur pour les flux
Lorsque vous travaillez avec io.Reader/io.Writer (corps HTTP, fichiers volumineux), utilisez Decoder et Encoder au lieu de tout charger en mémoire :
dec := json.NewDecoder(resp.Body)
var users []User
if err := dec.Decode(&users); err != nil {
return err
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(users)Decoder prend également en charge dec.Token() pour l'analyse du streaming pièce par pièce et dec.DisallowUnknownFields() pour rejeter JSON avec des clés inattendues (utile pour valider l'entrée).
Cartes génériques et any
Si vous ne connaissez pas le schéma, désérialisez en map[string]any :
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])Les valeurs auront des types dynamiques (string, float64 pour les nombres, []any, map[string]any, bool, nil).
Erreurs courantes
- Oubliez
&:json.Unmarshal(data, v)ne remplit rien ; vous avez besoin de&v. - Décoder la structure avec des champs nuls : Pour éviter la panique, vérifiez
errAVANT de lire les champs. - Types incompatibles : la désérialisation d'un nombre en chaîne ou vice versa renvoie
*json.UnmarshalTypeError.
Exercices
Sérialisez la structure u en JSON avec json.Marshal et imprimez le résultat sous forme de chaîne.
Solution disponible après 3 tentatives
Désérialisez `{"Name":"Ada"}` dans la struct U avec json.Unmarshal et imprimez-le.
Solution disponible après 3 tentatives
Le champ `name string` (minuscules) d'une structure est-il inclus par json.Marshal ?
type U struct {
name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))