言語バージョン 1.15.6

公開日 February 25, 2021, GMT+9

更新日 February 27, 2021, GMT+9

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}

1次情報

func Marshal - The Go Programming Language

JSON and Go - The Go Blog

Exported identifiers - The Go Programming Language