Ricerca…


Sintassi

  • func Marshal (v interface {}) ([] byte, errore)
  • func Errore Unmarshal (data [] byte, v interfaccia {})

Osservazioni

Il pacchetto "encoding/json" Package json implementa la codifica e la decodifica degli oggetti JSON in Go .


I tipi in JSON insieme ai tipi di calcestruzzo corrispondenti in Go sono:

Tipo JSON Vai tipo di cemento
booleano bool
numeri float64 o int
stringa stringa
nullo zero

Codifica JSON di base

json.Marshal dal pacchetto "encoding/json" codifica un valore per JSON.

Il parametro è il valore da codificare. I valori restituiti sono una matrice di byte che rappresentano l'input codificato JSON (in caso di successo) e un errore (in caso di errore).

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

Terreno di gioco

Ecco alcuni esempi di base di codifica per i tipi di dati incorporati:

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}

Terreno di gioco

La codifica di variabili semplici è utile per capire come funziona la codifica JSON in Go. Tuttavia, nel mondo reale, probabilmente codificherete dati più complessi memorizzati nelle strutture .

Decodifica JSON di base

json.Unmarshal dal pacchetto "encoding/json" decodifica un valore JSON nel valore indicato dalla variabile data.

I parametri sono il valore da decodificare in []bytes e una variabile da utilizzare come memoria per il valore de-serializzato. Il valore restituito è un errore (in caso di errore).

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]

Terreno di gioco

Si noti come nell'esempio precedente abbiamo saputo in anticipo sia il tipo di chiave che il valore. Ma questo non è sempre il caso. Di fatto, nella maggior parte dei casi il JSON contiene tipi di valori misti.

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"

Terreno di gioco

Nell'ultimo esempio sopra abbiamo usato una mappa generica per memorizzare il valore decodificato. Dobbiamo utilizzare un'interfaccia map[string]interface{} perché sappiamo che le chiavi sono stringhe, ma non conosciamo il tipo dei loro valori in anticipo.

Questo è un approccio molto semplice, ma è anche estremamente limitato. Nel mondo reale, generalmente decodificare un JSON in un tipo di struct definito dall'utente .

Decodifica dei dati JSON da un file

I dati JSON possono anche essere letti dai file.

Supponiamo di avere un file chiamato data.json con il seguente contenuto:

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

L'esempio seguente legge il file e decodifica il contenuto:

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

Il file data.json deve essere nella stessa directory del programma eseguibile Go. Leggi la documentazione di I / O sul file Go per ulteriori informazioni su come lavorare con i file in Go.

Utilizzo di strutture anonime per la decodifica

L'obiettivo con l'utilizzo di strutture anonime è quello di decodificare solo le informazioni che ci interessano senza sporcare la nostra app con tipi che vengono utilizzati solo in una singola funzione.

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

Terreno di gioco

Per il caso generale vedi anche: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-struct

Configurazione dei campi struct JSON

Considera il seguente esempio:

type Company struct {
    Name     string
    Location string
}

Nascondi / ignora determinati campi

Per esportare Revenue e Sales , ma nasconderli dalla codifica / decodifica, usa json:"-" o rinomina la variabile per iniziare con una lettera minuscola. Si noti che questo impedisce alla variabile di essere visibile all'esterno del pacchetto.

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

Ignora campi vuoti

Per evitare che Location venga incluso nel JSON quando è impostato sul suo valore zero, aggiungi ,omitempty al tag json .

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

Esempio nel parco giochi

Strutture di marshalling con campi privati

Come bravo sviluppatore hai creato la seguente struttura con campi sia esportati che non esportati:

type MyStruct struct {
    uuid string    
    Name string
}

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

Ora vuoi Marshal() questa struttura in JSON valido per l'archiviazione in qualcosa come ecc. Tuttavia, poiché uuid non viene esportato, json.Marshal() salta. Cosa fare? Usa una struttura anonima e l'interfaccia json.MarshalJSON() ! Ecco un esempio:

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
}

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

Codifica / decodifica usando le strutture di Go

Supponiamo di avere la seguente struct che definisce un tipo di City :

type City struct {  
    Name string  
    Temperature int  
}

Possiamo codificare / decodificare i valori della città usando il pacchetto encoding/json .

Prima di tutto, dobbiamo usare i metadati Go per dire al codificatore la corrispondenza tra i campi struct e le chiavi 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  
}  

Per mantenere semplice questo esempio, dichiareremo una corrispondenza esplicita tra i campi e le chiavi. Tuttavia, è possibile utilizzare diverse varianti del json: metadati come spiegato nei documenti .

IMPORTANTE: solo i campi esportati (campi con il nome maiuscolo) verranno serializzati / deserializzati. Ad esempio, se si nomina il campo t emperature , verrà ignorato anche se si impostano i metadati json .

Codifica

Per codificare una struttura di City , usa json.Marshal come nell'esempio di base:

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

Terreno di gioco

decodifica

Per decodificare una struttura di City , usa json.Unmarshal come nell'esempio di base:

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

Terreno di gioco



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow