In meinem letzten Blog, Go lernen, haben wir die Programmiersprache Go kennengelernt. Go ist eine moderne Systemprogrammiersprache, die sehr leicht zu erlernen ist, nativ auf Ihrem Betriebssystem läuft und keine Laufzeitumgebung benötigt, um zu funktionieren. Das macht Go sehr schnell und speichereffizient. Go verfügt über ein
Paket json
Das Paket json bietet Funktionen zur Kodierung und Dekodierung von JSON in Go-Werte. Das Paket bietet die Funktionen Marshal und Unmarshal.
Strukturen erstellen
Das json-Paket arbeitet mit Go-Strukturen. Um Go-Strukturen aus einer JSON-Nutzlast zu erzeugen, können wir das Online-Programm
Eingabe:
{
"location": "Amsterdam",
"weather": "sunny",
"temperature": 22,
"celsius": true,
"date": "2018-06-22T15:04:05Z",
"temp_forecast": [25, 26, 24, 20, 21, 22],
"wind": {
"direction": "SE",
"speed": 15
}
}
Ausgabe:
type AutoGenerated struct {
Location string json:"location"
Weather string json:"weather"
Temperature int json:"temperature"
Celsius bool json:"celsius"
Date string json:"date"
TempForecast []int json:"temp_forecast"
Wind struct {
Direction string json:"direction"
Speed int json:"speed"
} json:"wind"
}
Mit ein wenig Kopieren und Einfügen können wir es ein wenig aufräumen. Die Website erspart uns eine Menge Tipparbeit:
type Weather struct {
Location string json:"location"
Weather string json:"weather"
Temperature int json:"temperature"
Celsius bool json:"celsius"
Date string json:"date"
TempForecast []int json:"temp_forecast"
Wind Wind json:"wind"
}
type Wind struct {
Direction string json:"direction"
Speed int json:"speed"
}
Marschall Funktion
Um eine Go-Struktur in JSON zu serialisieren, rufen wir die Funktion Marshal mit einer Kopie der Struktur auf. Die Funktion gibt die JSON-Kodierung der Struktur als Byte-Array und einen optionalen Fehler zurück.
import (
"encoding/json"
"fmt"
"io/ioutil"
)
// serialize to json
bytes, _ := json.Marshal(GetWeatherData())
fmt.Println(string(bytes))
Unmarshal-Funktion
Um JSON in eine Go-Struktur zu deserialisieren, rufen wir die Funktion Unmarshal auf. Wir müssen zunächst eine Struktur vorbereiten und einen Zeiger auf die Struktur an die Unmarshal-Funktion übergeben. Die Funktion aktualisiert (mutiert) dann die Struktur und gibt alle Fehler als Ergebniswert zurück.
// read JSON from a file
data, _ := ioutil.ReadFile("weather.json")
// create a struct
weather := Weather{}
// pass the struct pointer to the unmarshal function
json.Unmarshal(data, &weather)
fmt.Print(weather)
Json Encoder Konfiguration
Die Kodierung von struct-Feldern kann durch den Format-String angepasst werden, der unter dem Schlüssel "json" im Tag des struct-Feldes gespeichert ist. Im Beispiel ist das struct-Tag der String, der auf die struct-Felder folgt, z.B.
// Field appears in JSON as key "myName".
Field int json:"myName"
// Field appears in JSON as key "myName" and
// the field is omitted from the object if its value is empty,
// as defined above.
Field int json:"myName,omitempty"
// Field appears in JSON as key "Field" (the default), but
// the field is skipped if empty.
// Note the leading comma.
Field int json:",omitempty"
// Field is ignored by this package.
Field int json:"-"
// Field appears in JSON as key "-".
Field int json:"-,"
// The "string" option signals that a field is stored as JSON inside a JSON-encoded string.
Int64String int64 json:",string"
Benutzerdefinierte Typen
Nehmen wir an, wir möchten das Datum als benutzerdefinierten Typ parsen lassen. Wir werden eine neue Struktur namens Date einführen, die aus einem Feld mit dem Feldnamen date serialisiert und deserialisiert wird:
type Date struct {
value time.Time
}
Wir müssen auch die Wetterstruktur aktualisieren:
type Wind struct {
Direction string json:"direction"
Speed int json:"speed"
}
type Weather struct {
Location string json:"location"
Weather string json:"weather"
Temperature int json:"temperature"
Celsius bool json:"celsius"
Date Date json:"date"
TempForecast []int json:"temp_forecast"
Wind Wind json:"wind"
}
Wir werden zwei neue Funktionen erstellen, die an die Schnittstelle des JSON-Encoders von Go angepasst sind. Die Encoder-Funktionen erweitern unsere Date.
func (w *Date) UnmarshalJSON(b []byte) error {
x := string("")
e := json.Unmarshal(b, &x)
if e != nil {
return e
}
t, err := time.Parse(time.RFC3339, x)
if err != nil {
return err
}
w.value = t
return nil
}
func (w Date) MarshalJSON() ([]byte, error) {
return json.Marshal(w.value.Format(time.RFC3339))
}
Go verfügt über genügend Informationen, um die gesamte Wetterstruktur zu serialisieren und zu deserialisieren. Wir haben die notwendigen Transformationsfunktionen für das Feld Date hinzugefügt.
Fazit
Es ist einfach, JSON-Datenstrukturen in Go-Strukturen zu serialisieren und zu deserialisieren. Der JSON-Encoder ist konfigurierbar, und mit Tags können wir den Encoder konfigurieren. Das json-Paket unterstützt die Erstellung neuer Serialisierer und Deserialisierer für benutzerdefinierte Typen. Wir haben einen benutzerdefinierten Serialisierer und Deserialisierer für den Typ Date erstellt, indem wir nur zwei Funktionen implementiert haben.
Verfasst von
Dennis Vriend
Contact
