Suche…
Syntax
- func Marshal (v interface {}) ([] Byte, Fehler)
- func Unmarshal (data [] byte, v interface {}) fehler
Bemerkungen
Das Paket "encoding/json"
Package json implementiert die Kodierung und Dekodierung von JSON-Objekten in Go
.
Typen in JSON mit ihren entsprechenden konkreten Typen in Go sind:
JSON-Typ | Gehen Sie konkrete Art |
---|---|
boolean | bool |
Zahlen | float64 oder int |
Schnur | Schnur |
Null | Null |
Grundlegende JSON-Kodierung
json.Marshal
aus dem Paket "encoding/json"
kodiert einen Wert in JSON.
Der Parameter ist der zu codierende Wert. Die zurückgegebenen Werte sind ein Byte-Array, das die JSON-codierte Eingabe (bei Erfolg) und einen Fehler (bei Fehler) darstellt.
decodedValue := []string{"foo", "bar"}
// encode the value
data, err := json.Marshal(decodedValue)
// check if the encoding is successful
if err != nil {
panic(err)
}
// print out the JSON-encoded string
// remember that data is a []byte
fmt.Println(string(data))
// "["foo","bar"]"
Hier einige grundlegende Beispiele für die Kodierung integrierter Datentypen:
var data []byte
data, _ = json.Marshal(1)
fmt.Println(string(data))
// 1
data, _ = json.Marshal("1")
fmt.Println(string(data))
// "1"
data, _ = json.Marshal(true)
fmt.Println(string(data))
// true
data, _ = json.Marshal(map[string]int{"London": 18, "Rome": 30})
fmt.Println(string(data))
// {"London":18,"Rome":30}
Die Kodierung einfacher Variablen ist hilfreich, um zu verstehen, wie die JSON-Kodierung in Go funktioniert. In der realen Welt werden Sie jedoch wahrscheinlich komplexere Daten verschlüsseln, die in Strukturen gespeichert sind .
Grundlegende JSON-Dekodierung
json.Unmarshal
aus dem Paket "encoding/json"
dekodiert einen JSON-Wert in den Wert, der von der angegebenen Variablen json.Unmarshal
wird.
Die Parameter sind der zu decodierende Wert in []bytes
und eine Variable, die als Speicher für den deserialisierten Wert verwendet werden soll. Der zurückgegebene Wert ist ein Fehler (bei einem Fehler).
encodedValue := []byte(`{"London":18,"Rome":30}`)
// generic storage for the decoded JSON
var data map[string]interface{}
// decode the value into data
// notice that we must pass the pointer to data using &data
err := json.Unmarshal(encodedValue, &data)
// check if the decoding is successful
if err != nil {
panic(err)
}
fmt.Println(data)
map[London:18 Rome:30]
Beachten Sie, dass wir im obigen Beispiel sowohl den Typ des Schlüssels als auch den Wert im Voraus kannten. Dies ist jedoch nicht immer der Fall. In den meisten Fällen enthält JSON gemischte Werttypen.
encodedValue := []byte(`{"city":"Rome","temperature":30}`)
// generic storage for the decoded JSON
var data map[string]interface{}
// decode the value into data
if err := json.Unmarshal(encodedValue, &data); err != nil {
panic(err)
}
// if you want to use a specific value type, we need to cast it
temp := data["temperature"].(float64)
fmt.Println(temp) // 30
city := data["city"].(string)
fmt.Println(city) // "Rome"
Im letzten Beispiel oben haben wir eine generische Karte verwendet, um den dekodierten Wert zu speichern. Wir müssen eine map[string]interface{}
da wir wissen, dass es sich bei den Schlüsseln um Strings handelt, aber wir kennen den Typ ihrer Werte nicht im Voraus.
Dies ist ein sehr einfacher Ansatz, der aber auch äußerst begrenzt ist. In der realen Welt würden Sie im Allgemeinen einen JSON in einen benutzerdefinierten struct
dekodieren .
JSON-Daten aus einer Datei decodieren
JSON-Daten können auch aus Dateien gelesen werden.
Nehmen wir an, wir haben eine Datei namens data.json
mit folgendem Inhalt:
[
{
"Name" : "John Doe",
"Standard" : 4
},
{
"Name" : "Peter Parker",
"Standard" : 11
},
{
"Name" : "Bilbo Baggins",
"Standard" : 150
}
]
Das folgende Beispiel liest die Datei und dekodiert den Inhalt:
package main
import (
"encoding/json"
"fmt"
"log"
"os"
)
type Student struct {
Name string
Standard int `json:"Standard"`
}
func main() {
// open the file pointer
studentFile, err := os.Open("data.json")
if err != nil {
log.Fatal(err)
}
defer studentFile.Close()
// create a new decoder
var studentDecoder *json.Decoder = json.NewDecoder(studentFile)
if err != nil {
log.Fatal(err)
}
// initialize the storage for the decoded data
var studentList []Student
// decode the data
err = studentDecoder.Decode(&studentList)
if err != nil {
log.Fatal(err)
}
for i, student := range studentList {
fmt.Println("Student", i+1)
fmt.Println("Student name:", student.Name)
fmt.Println("Student standard:", student.Standard)
}
}
Die Datei data.json
muss sich im selben Verzeichnis wie das ausführbare Programm von Go befinden. Weitere Informationen zur Arbeit mit Dateien in Go finden Sie in der Dokumentation zu Go File I / O.
Verwenden anonymer Strukturen zur Dekodierung
Das Ziel bei der Verwendung anonymer Strukturen ist es, nur die Informationen zu entschlüsseln, die uns wichtig sind, ohne unsere App mit Typen zu verschwenden, die nur in einer einzigen Funktion verwendet werden.
jsonBlob := []byte(`
{
"_total": 1,
"_links": {
"self": "https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=0",
"next": "https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25"
},
"subscriptions": [
{
"created_at": "2011-11-23T02:53:17Z",
"_id": "abcdef0000000000000000000000000000000000",
"_links": {
"self": "https://api.twitch.tv/kraken/channels/foo/subscriptions/bar"
},
"user": {
"display_name": "bar",
"_id": 123456,
"name": "bar",
"staff": false,
"created_at": "2011-06-16T18:23:11Z",
"updated_at": "2014-10-23T02:20:51Z",
"logo": null,
"_links": {
"self": "https://api.twitch.tv/kraken/users/bar"
}
}
}
]
}
`)
var js struct {
Total int `json:"_total"`
Links struct {
Next string `json:"next"`
} `json:"_links"`
Subs []struct {
Created string `json:"created_at"`
User struct {
Name string `json:"name"`
ID int `json:"_id"`
} `json:"user"`
} `json:"subscriptions"`
}
err := json.Unmarshal(jsonBlob, &js)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", js)
Ausgabe: {Total:1 Links:{Next:https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25} Subs:[{Created:2011-11-23T02:53:17Z User:{Name:bar ID:123456}}]}
Für den allgemeinen Fall siehe auch: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs
JSON-Strukturfelder konfigurieren
Betrachten Sie das folgende Beispiel:
type Company struct {
Name string
Location string
}
Bestimmte Felder ausblenden / überspringen
Um Revenue
und Sales
zu exportieren, sie jedoch vor dem Kodieren / Dekodieren zu verbergen, verwenden Sie json:"-"
oder benennen Sie die Variable um, um mit einem Kleinbuchstaben zu beginnen. Beachten Sie, dass dies verhindert, dass die Variable außerhalb des Pakets sichtbar ist.
type Company struct {
Name string `json:"name"`
Location string `json:"location"`
Revenue int `json:"-"`
sales int
}
Leere Felder ignorieren
Um zu verhindern , Location
von im JSON enthalten ist , wenn es um seinen Wert Null gesetzt wird, fügen ,omitempty
zum json
- Tag.
type Company struct {
Name string `json:"name"`
Location string `json:"location,omitempty"`
}
Marshaling-Strukturen mit privaten Feldern
Als guter Entwickler haben Sie folgende Struktur mit exportierten und nicht exportierten Feldern erstellt:
type MyStruct struct {
uuid string
Name string
}
Beispiel im Spielplatz: https://play.golang.org/p/Zk94Il2ANZ
Jetzt wollen Sie Marshal()
diese Struktur in gültige JSON für die Speicherung in so etwas wie ETCD. Da jedoch uuid
in nicht exportiert, die json.Marshal()
überspringt er. Was ist zu tun? Verwenden Sie eine anonyme Struktur und die Schnittstelle json.MarshalJSON()
! Hier ist ein Beispiel:
type MyStruct struct {
uuid string
Name string
}
func (m MyStruct) MarshalJSON() ([]byte, error {
j, err := json.Marshal(struct {
Uuid string
Name string
}{
Uuid: m.uuid,
Name: m.Name,
})
if err != nil {
return nil, err
}
return j, nil
}
Beispiel im Spielplatz: https://play.golang.org/p/Bv2k9GgbzE
Kodierung / Dekodierung mit Go-Strukturen
Nehmen wir an , wir haben die folgende struct
, die eine definiert City
Typ:
type City struct {
Name string
Temperature int
}
Wir können City-Werte mit dem encoding/json
Paket codieren / decodieren.
Als Erstes müssen wir mithilfe der Go-Metadaten dem Encoder die Entsprechung zwischen den Strukturfeldern und den JSON-Schlüsseln mitteilen.
type City struct {
Name string `json:"name"`
Temperature int `json:"temp"`
// IMPORTANT: only exported fields will be encoded/decoded
// Any field starting with a lower letter will be ignored
}
Um dieses Beispiel einfach zu halten, erklären wir eine explizite Entsprechung zwischen den Feldern und den Schlüsseln. Sie können jedoch mehrere Varianten der json:
-Metadaten verwenden, wie in den Dokumenten erläutert .
WICHTIG: Nur exportierte Felder (Felder mit Großnamen) werden serialisiert / deserialisiert. Wenn Sie beispielsweise das Feld t perperature benennen , wird es ignoriert, auch wenn Sie die json
Metadaten festlegen.
Codierung
Um eine City
Struktur zu codieren, verwenden Sie json.Marshal
wie im grundlegenden Beispiel:
// data to encode
city := City{Name: "Rome", Temperature: 30}
// encode the data
bytes, err := json.Marshal(city)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
// {"name":"Rome","temp":30}
Dekodierung
Um eine City
Struktur zu decodieren, verwenden Sie json.Unmarshal
wie im grundlegenden Beispiel:
// data to decode
bytes := []byte(`{"name":"Rome","temp":30}`)
// initialize the container for the decoded data
var city City
// decode the data
// notice the use of &city to pass the pointer to city
if err := json.Unmarshal(bytes, &city); err != nil {
panic(err)
}
fmt.Println(city)
// {Rome 30}