Lektionen des Moduls (5/5)
`encoding/json`
encoding/json ist das kanonische Paket zum Serialisieren von Go-Strukturen in JSON und zurück. Wenn Sie die Konventionen und Fallstricke kennen, ersparen Sie sich stundenlanges Debuggen von APIs und Konfigurationsdateien.
Marschall und Unmarschall
Die zwei Hauptfunktionen:
data, err := json.Marshal(v) // Go → []byte JSON
err = json.Unmarshal(data, &v) // JSON → Go (pass a pointer!)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)Für eine eingerückte Ausgabe (für Menschen lesbar) verwenden Sie json.MarshalIndent(v, "", " ").
Nur exportierte Felder
json.Marshal serialisiert nur exportierte Felder (Großbuchstaben). Private Felder werden stillschweigend ignoriert:
type U struct {
Name string // exported → serialized
age int // private → ignored
}Struktur-Tags: Steuern von Namen und Optionen
Die json:"..."-Tags steuern Name, Auslassung und Typen in der Ausgabe:
type User struct {
Name string `json:"name"` // rename
Email string `json:"email,omitempty"` // omit if zero value
Private string `json:"-"` // never serialized
ID int `json:"id,string"` // number as string
}Am häufigsten verwendete Optionen:
,omitempty– lässt das Feld weg, wenn es den Nullwert hat (0, "", Null, leeres Slice/Map).,-– nie serialisiert/deserialisiert.,string– wickelt Zahlen/Bools als Strings ein (nützlich für JS-IDs).
Decoder/Encoder für Streams
Wenn Sie mit io.Reader/io.Writer (HTTP-Text, große Dateien) arbeiten, verwenden Sie Decoder und Encoder, anstatt alles in den Speicher zu laden:
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 unterstützt auch dec.Token() für das Streaming-Stück-für-Stück-Parsing und dec.DisallowUnknownFields(), um JSON mit unerwarteten Schlüsseln abzulehnen (nützlich für die Eingabevalidierung).
Generische Karten und any
Wenn Sie das Schema nicht kennen, deserialisieren Sie es in map[string]any:
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])Werte haben dynamische Typen (string, float64 für Zahlen, []any, map[string]any, bool, nil).
Häufige Fehler
&vergessen:json.Unmarshal(data, v)füllt nichts auf; Sie benötigen&v.- Strukturen mit Nullfeldern dekodieren: Um Panik zu vermeiden, überprüfen Sie
err, BEVOR Sie Felder lesen. - Inkompatible Typen: Die Deserialisierung einer Zahl in eine Zeichenfolge oder umgekehrt gibt
*json.UnmarshalTypeErrorzurück.
Übungen
Serialisieren Sie die Struktur u mit json.Marshal in JSON und geben Sie das Ergebnis als Zeichenfolge aus.
Lösung nach 3 Versuchen verfügbar
Deserialisieren Sie `{"Name":"Ada"}` mit json.Unmarshal in die Struktur U und drucken Sie es aus.
Lösung nach 3 Versuchen verfügbar
Ist das Feld `name string` (Kleinbuchstaben) einer Struktur in json.Marshal enthalten?
type U struct {
name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))