サーチ…
構文
- 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
}
特定のフィールドを隠す/スキップする
Revenue
とSales
をエクスポートしてエンコード/デコードから隠すには、 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}