Zoeken…


Syntaxis

  • func Marshal (v interface {}) ([] byte, fout)
  • func Unmarshal (data [] byte, v interface {}) fout

Opmerkingen

Het pakket "encoding/json" Pakket json implementeert codering en decodering van JSON-objecten in Go .


Typen in JSON samen met hun bijbehorende betonsoorten in Go zijn:

JSON Type Ga concreet type
boolean bool
getallen float64 of int
draad draad
nul nul

Basis JSON-codering

json.Marshal uit het pakket "encoding/json" codeert een waarde voor JSON.

De parameter is de te coderen waarde. De geretourneerde waarden zijn een array van bytes die de JSON-gecodeerde invoer vertegenwoordigen (bij succes) en een fout (bij mislukking).

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

Speelplaats

Hier zijn enkele basisvoorbeelden van codering voor ingebouwde gegevenstypen:

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}

Speelplaats

Het coderen van eenvoudige variabelen is handig om te begrijpen hoe de JSON-codering werkt in Go. In de echte wereld zul je echter waarschijnlijk complexere gegevens coderen die zijn opgeslagen in structs .

Basic JSON-decodering

json.Unmarshal uit het pakket "encoding/json" decodeert een JSON-waarde in de waarde die wordt aangegeven door de gegeven variabele.

De parameters zijn de te decoderen waarde in []bytes en een variabele die moet worden gebruikt als opslag voor de gedeserialiseerde waarde. De geretourneerde waarde is een fout (bij mislukking).

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]

Speelplaats

Merk op hoe we in het bovenstaande voorbeeld van tevoren zowel het type sleutel als de waarde wisten. Maar dit is niet altijd het geval. In feite bevat de JSON in de meeste gevallen typen met gemengde waarden.

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"

Speelplaats

In het laatste voorbeeld hierboven hebben we een generieke kaart gebruikt om de gedecodeerde waarde op te slaan. We moeten een map[string]interface{} omdat we weten dat de sleutels tekenreeksen zijn, maar we weten niet van tevoren het type van hun waarden.

Dit is een heel eenvoudige aanpak, maar het is ook extreem beperkt. In de echte wereld zou u over het algemeen een JSON decoderen naar een op maat gedefinieerd struct type .

JSON-gegevens decoderen uit een bestand

JSON-gegevens kunnen ook uit bestanden worden gelezen.

Laten we aannemen dat we een bestand met de naam data.json met de volgende inhoud:

[
    {
      "Name" : "John Doe",
      "Standard" : 4
    },
    {
      "Name" : "Peter Parker",
      "Standard" : 11
    },
    {
      "Name" : "Bilbo Baggins",
      "Standard" : 150
    }
]

In het volgende voorbeeld wordt het bestand gelezen en wordt de inhoud gedecodeerd:

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

Het bestand data.json moet zich in dezelfde map bevinden als het uitvoerbare programma Go. Lees Go File I / O-documentatie voor meer informatie over het werken met bestanden in Go.

Anonieme structs gebruiken voor het decoderen

Het doel met het gebruik van anonieme structuren is om alleen de informatie te decoderen waar we om geven, zonder onze app te vervuilen met typen die alleen in één functie worden gebruikt.

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)

Output: {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}}]}

Speelplaats

Zie voor het algemene geval ook: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs

JSON struct-velden configureren

Overweeg het volgende voorbeeld:

type Company struct {
    Name     string
    Location string
}

Bepaalde velden verbergen / overslaan

Om Revenue en Sales te exporteren, maar ze te verbergen voor codering / decodering, gebruikt u json:"-" of hernoemt u de variabele om met een kleine letter te beginnen. Merk op dat dit voorkomt dat de variabele zichtbaar is buiten het pakket.

type Company struct {
    Name     string `json:"name"`
    Location string `json:"location"`
    Revenue  int    `json:"-"`
    sales    int
}

Negeer lege velden

Om te voorkomen dat Location wordt opgenomen in de JSON wanneer deze is ingesteld op de nulwaarde, voegt u ,omitempty aan de json tag.

type Company struct {
    Name     string `json:"name"`
    Location string `json:"location,omitempty"`
}

Voorbeeld in Speeltuin

Marshal structs met privévelden

Als een goede ontwikkelaar heb je de volgende struct gemaakt met zowel geëxporteerde als niet-geëxporteerde velden:

type MyStruct struct {
    uuid string    
    Name string
}

Voorbeeld in Playground: https://play.golang.org/p/Zk94Il2ANZ

Nu wil je Marshal() deze struct in geldige JSON voor opslag in zoiets als etcd. Echter, aangezien uuid in niet geëxporteerd, de json.Marshal() slaat het. Wat te doen? Gebruik een anonieme struct en de json.MarshalJSON() interface! Hier is een voorbeeld:

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
}

Voorbeeld in Playground: https://play.golang.org/p/Bv2k9GgbzE

Coderen / decoderen met behulp van Go-structs

Laten we aannemen dat we hebben de volgende struct die een definieert City soort:

type City struct {  
    Name string  
    Temperature int  
}

We kunnen City-waarden coderen / decoderen met behulp van het encoding/json pakket.

Allereerst moeten we de Go-metagegevens gebruiken om de encoder de correspondentie tussen de struct-velden en de JSON-sleutels te vertellen.

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  
}  

Om dit voorbeeld eenvoudig te houden, verklaren we een expliciete overeenkomst tussen de velden en de toetsen. U kunt echter verschillende varianten van de json: metadata gebruiken, zoals uitgelegd in de documenten .

BELANGRIJK: alleen geëxporteerde velden (velden met hoofdnaam) worden geserialiseerd / gedeserialiseerd. Als u bijvoorbeeld het veld t emperature een naam geeft , wordt het genegeerd, zelfs als u de json metagegevens json .

codering

Om een te coderen City structuur, gebruik json.Marshal zoals in het eenvoudig voorbeeld:

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

Speelplaats

decoderen

Om een decoderen City structuur, gebruik json.Unmarshal zoals in het eenvoudig voorbeeld:

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

Speelplaats



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow