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