json.Marshal
このページでは豊富な例を用いてGolangのjsonパッケージのMarshal関数の使い方を学ぶことができます。
Marshal関数はjsonパッケージの関数の1つです。
引数として与えた値をJSONに変換(エンコーディング)して返り値として返します。
返り値は2つあり、1つ目はJSONに変換された値([]byte型)、2つ目はerror型の値です。
// 記述例
import "encoding/json"
JSONに変換された値, エラー := json.Marshal(JSONに変換したい値)
TL;DR
基本
// 第1引数にJSONに変換したい値を指定する
// 構造体(struct)の場合
type Person struct {
ID int
Name string
}
person1 := Person{ID: 1, Name: "Alisha"}
fmt.Printf("%+v\n", person1)
==> {ID:1 Name:Alisha}
returnValue1, err := json.Marshal(person1)
if err != nil {
fmt.Println(err)
}
// そのまま出力すると[]byte型([]uint8型)の値
fmt.Println(returnValue1)
==> [123 34 73 68 34 58 49 44 34 78 97 109 101 34 58 34 65 108 105 115 104 97 34 125]
fmt.Printf("%T\n", returnValue1)
==> []uint8
// JSONの文字列に変換して確認
fmt.Printf("%s\n", returnValue1)
==> {"ID":1,"Name":"Alisha"}
// 配列の場合
array2 := [3]string{"go", "golang", "gopher"}
returnValue2, _ := json.Marshal(array2)
fmt.Printf("%s\n", returnValue2)
==> ["go","golang","gopher"]
// スライスの場合
slice3 := []bool{true, true, false}
returnValue3, _ := json.Marshal(slice3)
fmt.Printf("%s\n", returnValue3)
==> [true,true,false]
// 文字列(string)の場合
returnValue4, _ := json.Marshal("Golang")
fmt.Printf("%s\n", returnValue4)
==> "Golang"
// マップ(map)の場合
map1 := map[int]string{0: "go", 1: "golang"}
returnValue5, _ := json.Marshal(map1)
fmt.Printf("%s\n", returnValue5)
==> {"0":"go","1":"golang"}
// nilの場合
returnValue6, _ := json.Marshal(nil)
fmt.Printf("%s\n", returnValue6)
==> null
// 構造体の場合.2
type Language struct {
Name string
Packages []string
Contributors []string
}
language7 := Language{Packages: []string{}, Contributors: nil}
fmt.Printf("%+v\n", language7)
==> {Name: Packages:[] Contributors:[]}
returnValue7, _ := json.Marshal(language7)
fmt.Printf("%s\n", returnValue7)
==> {"Name":"","Packages":[],"Contributors":null}
関連情報:array型(配列)の解説
関連情報:slice型(スライス)の解説
関連情報:map型(マップ)の解説
フィールドタグを使用したキー名の変更
// パッケージ外からアクセスできないフィールド(Non-exported fields、小文字で始まるフィールド)はJSONに変換されない
type Person struct {
ID int
name string
}
person1 := Person{ID: 1, name: "Ayaan"}
fmt.Printf("%+v\n", person1)
==> {ID:1 name:Ayaan}
returnValue1, _ := json.Marshal(person1)
fmt.Printf("%s\n", returnValue1)
==> {"ID":1}
// フィールドタグでJSON変換時の名前を指定できる
type Language struct {
ID int
Name string `json:"lang_name"`
Country string `json:"lang_country"`
}
language1 := Language{ID: 1, Name: "Japanese", Country: "Japan"}
fmt.Printf("%+v\n", language1)
==> {ID:1 Name:Japanese Country:Japan}
// jsonというキーを指定したフィールドタグのJSON内の名前が変更されている
returnValue2, _ := json.Marshal(language1)
fmt.Printf("%s\n", returnValue2)
==> {"ID":1,"lang_name":"Japanese","lang_country":"Japan"}
他のフィールドタグの指定
// omitemptyの指定.1
type Person1 struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
IsStudent bool `json:"is_student,omitempty"`
}
// ゼロ値・空値(zero value, empty value)のフィールドがJSONに変換されない
person1 := Person1{ID: 0, Name: "Mengdie", IsStudent: false}
returnValue1, _ := json.Marshal(person1)
fmt.Printf("%s\n", returnValue1)
==> {"name":"Mengdie"}
// omitemptyの指定.2
type Person2 struct {
ID int `json:",omitempty"`
Name string `json:",omitempty"`
IsStudent bool `json:",omitempty"`
}
// フィールド名はそのままで、omitemptyのみ適用させる
person2 := Person2{ID: 1, Name: "", IsStudent: true}
returnValue2, _ := json.Marshal(person2)
fmt.Printf("%s\n", returnValue2)
==> {"ID":1,"IsStudent":true}
// "-"の指定.1
type Person3 struct {
ID int `json:"-"`
Name string
}
// 指定したフィールドは常にJSONに変換されない
person3 := Person3{ID: 1, Name: "Mengdie"}
returnValue3, _ := json.Marshal(person3)
fmt.Printf("%s\n", returnValue3)
==> {"Name":"Mengdie"}
// "-"の指定.2
type Person4 struct {
ID int `json:"-,"`
Name string
}
// "-,"で指定すると"-"がJSON変換時のフィールド名となる
person4 := Person4{ID: 1, Name: "Mengdie"}
returnValue4, _ := json.Marshal(person4)
fmt.Printf("%s\n", returnValue4)
==> {"-":1,"Name":"Mengdie"}
jsonからの変換
type Vegetable struct {
Name string
Price int
}
// JSONへの変換
vegetable1 := Vegetable{Name: "carrot", Price: 300}
returnValue1, _ := json.Marshal(vegetable1)
fmt.Printf("%s\n", returnValue1)
==> {"Name":"carrot","Price":300}
// Unmarshal関数を使用してJSONから構造体へ変換(デコード)
var vegetable2 Vegetable
err := json.Unmarshal(returnValue1, &vegetable2)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%+v\n", vegetable2)
==> {Name:carrot Price:300}
関連情報:json.Unmarshalの使用方法
解説
// 記述例
import "encoding/json"
JSONに変換された値, エラー := json.Marshal(JSONに変換したい値)
基本
Marshal関数は引数で与えた値をJSONへ変換し、返り値として返します。
引数にはinterface{}
型、つまりすべての型の値を指定することができ、与えた値によりJSONに変換した際の形式が異なります。
返り値は2つあり、1つ目はJSONに変換された値([]byte型)、2つ目はJSONへ変換する際に発生したエラーを返します。
エラーが発生しない場合は2つ目の返り値はnil
となります。
// 構造体(struct)
type Fruit struct {
Name string
Price int
}
fruit1 := Fruit{Name: "Kiwi", Price: 100}
fmt.Printf("%+v\n", fruit1)
==> {Name:Kiwi Price:100}
returnValue1, err := json.Marshal(fruit1)
if err != nil {
fmt.Println(err)
}
// 返り値は[]byte型([]uint8)
fmt.Println(returnValue1)
==> [123 34 78 97 109 101 34 58 34 75 105 119 105 34 44 34 80 114 105 99 101 34 58 49 48 48 125]
fmt.Printf("%T\n", returnValue1)
==> []uint8
// JSONを文字列として出力
fmt.Printf("%s\n", returnValue1)
==> {"Name":"Kiwi","Price":100}
// 配列
array2 := [2]int{100, 200}
returnValue2, _ := json.Marshal(array2)
fmt.Printf("%s\n", returnValue2)
==> [100,200]
// スライスの場合
slice3 := []string{"Go", "Golang"}
returnValue3, _ := json.Marshal(slice3)
fmt.Printf("%s\n", returnValue3)
==> ["Go","Golang"]
// マップ(map)の場合
map4 := map[int]bool{1: true, 2: false}
returnValue4, _ := json.Marshal(map4)
fmt.Printf("%s\n", returnValue4)
==> {"1":true,"2":false}
// 文字列(string)の場合
returnValue5, _ := json.Marshal("FooBarNinja")
fmt.Printf("%s\n", returnValue5)
==> "FooBarNinja"
// nilの場合
returnValue6, _ := json.Marshal(nil)
fmt.Printf("%s\n", returnValue6)
==> null
// 構造体.2
type User struct {
ID int
Friends []string
Favorites map[string]int
}
user7 := User{Friends: []string{}, Favorites: nil}
fmt.Printf("%+v\n", user7)
==> {ID:0 Friends:[] Favorites:map[]}
returnValue7, _ := json.Marshal(user7)
fmt.Printf("%s\n", returnValue7)
==> {"ID":0,"Friends":[],"Favorites":null}
関連情報:array型(配列)の解説
関連情報:slice型(スライス)の解説
関連情報:map型(マップ)の解説
フィールドタグを使用したキー名の変更
構造体(struct)をMarshal関数でJSONに変換する場合、構造体のフィールドタグを使用してJSONに変換された場合のキー名(フィールド名)を指定することができます。
この場合、フィールドタグにはjson
というキーを指定し、:
(コロン)の後に"
(ダブルクオーテーション)で囲んだJSON変換後のキー名を指定します。
また、同一パッケージ外からアクセスできないフィールド(Non-exported fields、大文字で始まらないフィールド)は、JSON変換後のフィールドに含まれないので注意してください。
// 小文字で始まるフィールド(Non-exported fields)を含む構造体
type Fruit struct {
Name string
price int
}
fruit1 := Fruit{Name: "Apple", price: 100}
fmt.Printf("%+v\n", fruit1)
==> {Name:Apple price:100}
returnValue1, _ := json.Marshal(fruit1)
fmt.Printf("%s\n", returnValue1)
==> {"Name":"Apple"}
// フィールドタグでJSON変換時の名前を指定できる
type Person struct {
ID int
Name string `json:"person_name"`
}
person1 := Person{ID: 1, Name: "Olivia"}
fmt.Printf("%+v\n", person1)
==> {ID:1 Name:Olivia}
// JSON内の名前がタグで指定した名前に変更される
returnValue2, _ := json.Marshal(person1)
fmt.Printf("%s\n", returnValue2)
==> {"ID":1,"person_name":"Olivia"}
他のフィールドタグの指定
Marshal関数とフィールドタグを使用すると、JSON変換後のキー名を変更するだけでなく、その他の振る舞いをさせることもできます。
このページではomitempty
と-
を紹介します。
より詳しい説明や他のオプションは
公式のMarshal関数の解説
を参照してください。
omitempty
フィールドタグのjsonキーに指定することで、フィールドの値がゼロ値・空値(zero value, empty value)だった場合に該当フィールドをJSONに変換させない。
JSON変換後のフィールド名を変更しない場合は、,omitempty
と指定する。
"-"
フィールドタグのjsonキーに指定することで、指定したフィールドをJSONに変換しない。
このオプションを使用する場合はJSON変換後のフィールド名を指定できないことに注意してください。
// omitemptyの指定.1
type Student1 struct {
Name string `json:"name,omitempty"`
GPA float32 `json:"gpa,omitempty"`
IsScholarship bool `json:"is_scholarship,omitempty"`
}
// ゼロ値・空値(zero value, empty value)のフィールドがJSONに変換されない
student1 := Student1{Name: "", GPA: 3.5, IsScholarship: false}
returnValue1, _ := json.Marshal(student1)
fmt.Printf("%s\n", returnValue1)
==> {"gpa":3.5}
// omitemptyの指定.2
type Student2 struct {
Name string `json:",omitempty"`
GPA float32 `json:",omitempty"`
IsScholarship bool `json:",omitempty"`
}
// フィールド名を変更せず、omitemptyのみ適用させる
student2 := Student2{Name: "Junjie", GPA: 3.8, IsScholarship: false}
returnValue2, _ := json.Marshal(student2)
fmt.Printf("%s\n", returnValue2)
==> {"Name":"Junjie","GPA":3.8}
// "-"の指定.1
type Student3 struct {
Name string `json:"-"`
GPA float32
}
// 指定したフィールドは常にJSONに変換されない
student3 := Student3{Name: "Junjie", GPA: 3.8}
returnValue3, _ := json.Marshal(student3)
fmt.Printf("%s\n", returnValue3)
==> {"GPA":3.8}
// "-"の指定.2
type Student4 struct {
Name string
GPA float32 `json:"-"`
}
// "-,"で指定すると"-"がJSON変換時のフィールド名となる
student4 := Student4{Name: "Junjie", GPA: 3.8}
returnValue4, _ := json.Marshal(student4)
fmt.Printf("%s\n", returnValue4)
==> {"Name":"Junjie"}
jsonからの変換
JSON形式のデータからGo言語の型のデータに変換する場合、同じjsonパッケージのUnmarshal関数を使用できます。
一例を以下のコード例に載せます。より詳しく知りたい場合は下記のUnmarshal関数の解説ページを参照してください。
関連情報:json.Unmarshalの使用方法
type Student struct {
ID int
Name string
}
// 構造体からJSONへの変換
student1 := Student{ID: 1, Name: "Sara"}
returnValue1, _ := json.Marshal(student1)
fmt.Printf("%s\n", returnValue1)
==> {"ID":1,"Name":"Sara"}
// JSONから構造体への変換
var student2 Student
err := json.Unmarshal(returnValue1, &student2)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%+v\n", student2)
==> {ID:1 Name:Sara}