Sök…


Syntax

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

Anmärkningar

Paketet "encoding/json" Paketet json implementerar kodning och avkodning av JSON-objekt i Go .


Typer i JSON tillsammans med motsvarande betongtyper i Go är:

JSON-typ Gå betongtyp
boolean bool
tal float64 eller int
sträng sträng
null noll

Grundläggande JSON-kodning

json.Marshal från paketet "encoding/json" kodar ett värde till JSON.

Parametern är värdet som ska kodas. De returnerade värdena är en matris med byte som representerar den JSON-kodade ingången (vid framgång) och ett fel (vid fel).

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

Lekplats

Här är några grundläggande exempel på kodning för inbyggda datatyper:

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}

Lekplats

Kodning av enkla variabler är bra för att förstå hur JSON-kodningen fungerar i Go. Men i den verkliga världen kommer du sannolikt att koda mer komplexa data lagrade i strukturer .

Grundläggande avkodning av JSON

json.Unmarshal från paketet "encoding/json" avkodar ett JSON-värde till det värde som pekas av den givna variabeln.

Parametrarna är värdet som avkodas i []bytes och en variabel som ska användas som lagring för det avserialiserade värdet. Det returnerade värdet är ett fel (vid fel).

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]

Lekplats

Lägg märke till hur vi i exemplet ovan i förväg visste både typ av nyckel och värde. Men detta är inte alltid fallet. I de flesta fall innehåller JSON faktiskt blandade värdetyper.

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"

Lekplats

I det sista exemplet ovan använde vi en generisk karta för att lagra det avkodade värdet. Vi måste använda ett map[string]interface{} eftersom vi vet att nycklarna är strängar, men vi vet inte vilken typ av värden de har i förväg.

Detta är ett mycket enkelt tillvägagångssätt, men det är också extremt begränsat. I den verkliga världen skulle du generellt avkoda en JSON till en specialdefinierad struct .

Avkodning av JSON-data från en fil

JSON-data kan också läsas från filer.

Låt oss anta att vi har en fil som heter data.json med följande innehåll:

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

Följande exempel läser filen och avkodar innehållet:

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

data.json måste finnas i samma katalog för Go-körbara programmet. Läs I / O-dokumentation för Go File för mer information om hur du arbetar med filer i Go.

Använda anonyma strukturer för avkodning

Målet med att använda anonyma strukturer är att avkoda bara den information vi bryr oss om utan att kasta vår app med typer som endast används i en enda funktion.

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

Lekplats

För det allmänna fallet, se även: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs

Konfigurera JSON-strukturfält

Tänk på följande exempel:

type Company struct {
    Name     string
    Location string
}

Dölj / hoppa över vissa fält

För att exportera Revenue och Sales men dölja dem från att koda / avkoda använder du json:"-" eller byter namn på variabeln för att börja med en liten bokstav. Observera att detta förhindrar att variabeln syns utanför paketet.

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

Ignorera tomma fält

För att förhindra att Location ingår i JSON när den är inställd på dess nollvärde, lägg till ,omitempty till json taggen.

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

Exempel på lekplats

Marshalera strukturer med privata fält

Som en bra utvecklare har du skapat följande struktur med både exporterade och icke-exporterade fält:

type MyStruct struct {
    uuid string    
    Name string
}

Exempel på lekplats: https://play.golang.org/p/Zk94Il2ANZ

Nu vill du Marshal() denna struktur till giltig JSON för lagring i något liknande etcd. Eftersom uuid inte har exporterats json.Marshal() över det. Vad ska man göra? Använd en anonym struktur och json.MarshalJSON() ! Här är ett exempel:

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
}

Exempel på lekplats: https://play.golang.org/p/Bv2k9GgbzE

Kodning / avkodning med Go-strukturer

Låt oss anta att vi har följande struct som definierar en City typ:

type City struct {  
    Name string  
    Temperature int  
}

Vi kan koda / avkoda stadsvärden med encoding/json paketet.

Först av allt måste vi använda Go-metadata för att berätta för kodaren överensstämmelse mellan strukturfälten och JSON-tangenterna.

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  
}  

För att hålla detta exempel enkelt, förklarar vi en uttrycklig korrespondens mellan fälten och nycklarna. Du kan dock använda flera varianter av json: metadata som förklaras i dokumenten .

VIKTIGT: Endast exporterade fält (fält med huvudnamn) kommer att serialiseras / deserialiseras. Om du till exempel namnger fältet t emperatur ignoreras det även om du ställer in json metadata.

kodning

Att koda en City struct använder json.Marshal som i grund exempel:

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

Lekplats

avkodning

För att avkoda en City struct använder json.Unmarshal som i grund exempel:

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

Lekplats



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow