サーチ…


構文

  • func Marshal(v interface {})([]バイト、エラー)
  • func Unmarshal(data [] byte、v interface {})エラー

備考

パッケージ"encoding/json"パッケージjsonは、 GoでJSONオブジェクトのエンコードとデコードを実装しています。


JSONの型とGoの対応する具体的な型は次のとおりです。

JSONタイプゴーコンクリートタイプ
ブール値ブール
数字 float64またはint
文字列文字列
ヌルなし

基本JSONエンコーディング

パッケージ"encoding/json"からのjson.Marshalは値をJSONにエンコードします。

パラメータはエンコードする値です。返される値はJSONエンコードされた入力を表すバイト配列(成功時)とエラー(失敗時)です。

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

遊び場

組み込みデータ型のエンコーディングの基本的な例を次に示します。

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}

遊び場

単純変数のエンコーディングは、JSONエンコーディングがGoでどのように機能するかを理解するのに役立ちます。しかし、現実の世界では、構造体に格納されたより複雑なデータをエンコードする可能性があります。

基本JSONデコード

json.Unmarshalパッケージの"encoding/json"はJSON値を指定された変数が指す値にデコードします。

パラメータは、 []bytesデコードする値と、デシリアライズされた値の記憶域として使用する変数です。戻り値はエラー(失敗時)です。

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]

遊び場

上記の例では、キーのタイプと値の両方を事前に知っていたことに注意してください。しかし、これは必ずしもそうではありません。実際、ほとんどの場合、JSONには混合値型が含まれています。

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"

遊び場

上記の最後の例では、デコードされた値を格納するための汎用マップを使用しました。キーが文字列であることがわかっているのでmap[string]interface{}使用する必要がありますが、事前にその値の型がわかりません。

これは非常に簡単なアプローチですが、非常に限られています。現実の世界では、JSONを一般にカスタム定義のstructデコードします

JSONデータをファイルからデコードする

JSONデータはファイルから読み取ることもできます。

次の内容のdata.jsonというファイルがあるとします。

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

次の例では、ファイルを読み取り、コンテンツをデコードします。

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ファイルは、Go実行可能プログラムと同じディレクトリになければなりません。 Goでファイルを操作する方法の詳細については、 Go File I / Oのドキュメントを参照してください。

デコードに匿名の構造体を使用する

匿名の構造体を使用することの目標は、私たちの気になる情報のみをデコードすることです.1つの関数でのみ使用される型でアプリケーションを捨てることはありません。

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)

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

遊び場

一般的なケースについては、以下も参照してください。http : //stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs

JSON構造体フィールドの設定

次の例を考えてみましょう。

type Company struct {
    Name     string
    Location string
}

特定のフィールドを隠す/スキップする

RevenueSalesをエクスポートしてエンコード/デコードから隠すには、 json:"-"使用するか、変数の名前を小文字で始めるように変更します。これにより、変数がパッケージの外側に表示されなくなります。

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

空のフィールドを無視する

ゼロ値に設定されているときにLocationがJSONに含まれないようにするには、 jsonタグに,omitemptyを追加します。

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

プレイグラウンドの例

privateフィールドを持つ構造体のマーシャリング

良い開発者として、次の構造体をエクスポートフィールドと非エクスポートフィールドの両方で作成しました。

type MyStruct struct {
    uuid string    
    Name string
}

プレイグラウンドの例: https : //play.golang.org/p/Zk94Il2ANZ

これで、この構造体を有効なJSONにMarshal()して、etcdなどのストレージに保管したいとします。しかし、 uuidがエクスポートされていないので、 json.Marshal()はスキップします。何をすべきか?匿名の構造体とjson.MarshalJSON()インタフェースを使用してください!ここに例があります:

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
}

プレイグラウンドの例: https : //play.golang.org/p/Bv2k9GgbzE

Go構造体を使用したエンコード/デコード

City型を定義する次のstructがあるとしましょう:

type City struct {  
    Name string  
    Temperature int  
}

encoding/jsonパッケージを使用してCity値をエンコード/デコードできます。

まず、構造体フィールドとJSONキーの対応をエンコーダに伝えるために、Goメタデータを使用する必要があります。

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  
}  

この例を単純にするために、フィールドとキーの間の明示的な対応を宣言します。しかし、 ドキュメントで説明されているように、 json:メタデータのいくつかの変種を使用することができます。

重要: エクスポートされたフィールド (大文字のフィールドを持つフィールド)のみがシリアライズ/デシリアライズされます。あなたは、フィールドのT emperatureに名前付ける場合たとえば、あなたが設定しても無視されますjsonメタデータを。

エンコーディング

City構造体をエンコードするには、基本的な例のようにjson.Marshalを使用します。

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

遊び場

デコード

City構造体をデコードするには、基本的な例のようにjson.Unmarshalを使用します。

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

遊び場



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow