Szukaj…


Składnia

  • func Marshal (v interface {}) ([] bajt, błąd)
  • func Unmarshal (data [] bajt, v interfejs {}) błąd

Uwagi

Pakiet "encoding/json" Pakiet json implementuje kodowanie i dekodowanie obiektów JSON w Go .


Typy w JSON wraz z odpowiadającymi im konkretnymi typami w Go to:

Typ JSON Wybierz rodzaj betonu
boolean bool
liczby float64 lub int
strunowy strunowy
zero zero

Podstawowe kodowanie JSON

json.Marshal z pakietu "encoding/json" koduje wartość do JSON.

Ten parametr jest wartością do zakodowania. Zwracane wartości to tablica bajtów reprezentujących dane wejściowe zakodowane w JSON (w przypadku powodzenia) i błąd (w przypadku niepowodzenia).

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

Plac zabaw

Oto kilka podstawowych przykładów kodowania wbudowanych typów danych:

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}

Plac zabaw

Kodowanie prostych zmiennych pomaga zrozumieć, jak działa kodowanie JSON w Go. Jednak w prawdziwym świecie prawdopodobnie kodujesz bardziej złożone dane przechowywane w strukturach .

Podstawowe dekodowanie JSON

json.Unmarshal z pakietu "encoding/json" dekoduje wartość JSON na wartość wskazywaną przez daną zmienną.

Parametry to wartość do zdekodowania w []bytes i zmienna, która ma być używana jako pamięć dla wartości bez serializacji. Zwrócona wartość jest błędem (w przypadku awarii).

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]

Plac zabaw

Zauważ, że w powyższym przykładzie z góry znaliśmy zarówno rodzaj klucza, jak i wartość. Lecz nie zawsze tak jest. W rzeczywistości w większości przypadków JSON zawiera mieszane typy wartości.

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"

Plac zabaw

W ostatnim przykładzie powyżej użyliśmy ogólnej mapy do przechowywania zdekodowanej wartości. Musimy użyć map[string]interface{} ponieważ wiemy, że klucze są łańcuchami, ale nie znamy z góry rodzaju ich wartości.

Jest to bardzo proste podejście, ale również bardzo ograniczone. W świecie rzeczywistym dekodowałbyś JSON na niestandardowy typ struct .

Dekodowanie danych JSON z pliku

Dane JSON można również odczytać z plików.

Załóżmy, że mamy plik o nazwie data.json o następującej treści:

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

Poniższy przykład czyta plik i dekoduje zawartość:

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

Plik data.json musi znajdować się w tym samym katalogu programu wykonywalnego Go. Przeczytaj dokumentację We / Wy pliku Go, aby uzyskać więcej informacji na temat pracy z plikami w Go.

Korzystanie z anonimowych struktur do dekodowania

Celem korzystania z anonimowych struktur jest odkodowanie tylko tych informacji, na których nam zależy, bez zaśmiecania naszej aplikacji typami używanymi tylko w jednej funkcji.

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)

Dane wyjściowe: {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}}]}

Plac zabaw

Ogólny przypadek zobacz także: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs

Konfigurowanie pól struktury JSON

Rozważ następujący przykład:

type Company struct {
    Name     string
    Location string
}

Ukryj / pomiń niektóre pola

Aby wyeksportować Revenue i Sales , ale ukryć je przed kodowaniem / dekodowaniem, użyj json:"-" lub zmień nazwę zmiennej, aby rozpocząć od małej litery. Zauważ, że zapobiega to widoczności zmiennej poza pakietem.

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

Zignoruj puste pola

Aby zapobiec Location przed zawarte w JSON, gdy jest on ustawiony na wartość zerową, należy dodać ,omitempty do json tagu.

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

Przykład na placu zabaw

Gromadzenie struktur z polami prywatnymi

Jako dobry programista stworzyłeś następującą strukturę z polami wyeksportowanymi i nieeksportowanymi:

type MyStruct struct {
    uuid string    
    Name string
}

Przykład na placu zabaw: https://play.golang.org/p/Zk94Il2ANZ

Teraz chcesz Marshal() tę strukturę do prawidłowego JSON do przechowywania w coś takiego jak etcd. Jednak ponieważ uuid nie jest eksportowany, json.Marshal() pomija go. Co robić? Użyj anonimowej struktury i interfejsu json.MarshalJSON() ! Oto przykład:

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
}

Przykład w Playground: https://play.golang.org/p/Bv2k9GgbzE

Kodowanie / dekodowanie za pomocą struktur Go

Załóżmy, że mamy następującą struct która definiuje typ City :

type City struct {  
    Name string  
    Temperature int  
}

Możemy kodować / dekodować wartości City za pomocą pakietu encoding/json .

Przede wszystkim musimy użyć metadanych Go, aby poinformować koder o zgodności między polami strukturalnymi a kluczami JSON.

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  
}  

Aby uprościć ten przykład, zadeklarujemy wyraźną korespondencję między polami a kluczami. Można jednak użyć kilku wariantów json: metadanych, jak wyjaśniono w dokumentacji .

WAŻNE: Tylko wyeksportowane pola (pola z nazwą kapitału) będą serializowane / deserializowane. Na przykład, jeśli nazwiesz pole t emperatura , zostanie ono zignorowane, nawet jeśli ustawisz metadane json .

Kodowanie

Aby zakodować strukturę City , użyj json.Marshal jak w podstawowym przykładzie:

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

Plac zabaw

Rozszyfrowanie

Aby zdekodować strukturę City , użyj json.Unmarshal jak w podstawowym przykładzie:

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

Plac zabaw



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow