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"]"

Spielplatz

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}

Spielplatz

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]

Spielplatz

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"

Spielplatz

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}}]}

Spielplatz

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"`
}

Beispiel im Spielplatz

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} 

Spielplatz

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} 

Spielplatz



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow