ProgrammierungBackend Go Entwickler

Wie wird die Arbeit mit JSON (encoding/json) in Go umgesetzt: Besonderheiten der Serialisierung, Besonderheiten der Struct-Tags, häufige Probleme beim Marshaling/Unmarshaling und Workarounds?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

In Go wird das JSON-Marshaling standardmäßig über das Paket encoding/json implementiert. Es können nur exportierte (mit großem Anfangsbuchstaben) Felder von Strukturen serialisiert werden. Zur Steuerung der Namen und Verarbeitung werden Struct-Tags verwendet:

type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
  • omitempty schließt das Feld bei einem Nullwert aus;
  • string serialisiert den Wert als Zeichenkette, selbst wenn es eine Zahl ist.

Beispiel für die Serialisierung:

user := User{ID: 1, Name: "Oleg"} b, _ := json.Marshal(user) fmt.Println(string(b)) // {"id":1,"name":"Oleg","age":"0"}

Beispiel für das Parsen von JSON

var u User json.Unmarshal([]byte('{"id":2,"name":"Ivan"}'), &u)

Fangfrage.

Wie werden nicht exportierte (mit kleinem Anfangsbuchstaben) Felder von Strukturen beim Marshaling in JSON serialisiert?

Richtige Antwort: Sie werden ignoriert, bei der Serialisierung werden nur exportierte (mit großem Anfangsbuchstaben) Felder einbezogen. Dies kann API unerwartet brechen:

type Foo struct { bar int // wird nicht serialisiert! }

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas.


Geschichte

Das Backend lieferte unvollständige JSON-Objekte, weil einige erforderliche Felder nicht exportiert waren (mit kleinem Anfangsbuchstaben). Es dauerte mehrere Tage, um herauszufinden, warum die Clients diese Felder nicht sehen konnten.


Geschichte

Im API-Antwortfeld war die Konstruktion omitempty enthalten, aber manchmal kam ein leerer Wert zurück, weil der Nullwert für einen Slice nil ist und nicht ein leerer Slice. Die Clients erhielten null anstelle eines leeren Arrays [] und stürzten beim Parsen ab.


Geschichte

Im Projekt wurden dynamische Felder zu Strukturen über map[string]interface hinzugefügt, aber es wurde vergessen, ein benutzerdefiniertes UnmarshalJSON zu implementieren, wodurch ein Teil der Daten ohne Fehler "verloren" ging. Kundendaten gingen verloren und mussten manuell aus Backups wiederhergestellt werden.