0
0

GoでのJSON エンコードとデコードの基本

Last updated at Posted at 2024-05-26

はじめに

この記事では、Goを使用してJSON形式のデータする方法について解説します。標準ライブラリであるencoding/jsonパッケージを使用して、Gonoデータ構造とJSON形式のデータを相互に変換する方法をサンプルコードを用いて説明します。

想定読者

  • Go構造体 <-> JSON形式の変換方法を知りたい駆け出しGopher
  • Goの構造体型への基本的な理解
  • JSONが何かわかる

記事の狙い

  • Go言語におけるJSONのエンコードとデコードの基本的な使い方を理解する

結論

  • 構造体タグを使ってJSONオブジェクトのフィールドとGo構造体のフィールドをマッチングする
    • jsonというタグ名を使ってJSONフィールドを指定する
// 構造体タグを使ったフィールド名の指定
type Person struct {
    Name   string `json:"name"`
    Age    int    `json:"age"`
    Email  string `json:"email"`
}
  • JSONエンコード(Go構造体 -> JSON形式)
    • Marshal関数を使う
  • JSONデコード(JSON形式 -> Go構造体)
    • Unmarshal関数を使う

encoding/json

Goの標準ライブラリであるencoding/jsonライブラリはGoのデータ型とJSON間で相互に変換する機能を持っています。

  • Goのデータ型からJSON形式への変換は マーシャリング(marshaling) と呼ばれる
  • JSON形式からGoのデータ型への変換は アンマーシャリング(unmarshaling) と呼ばれる

構造体タグを使ったメタデータの付加

構造体タグを使うことで、JSON形式のデータとGoのデータ型の対応付けを行うことができます。構造体タグのルールは以下のようになっています。

  • 構造体タグはバッククォート(`)で囲まれた文字列として定義される
  • 構造体タグが行を跨ぐことはない
  • `json:"key"`の形式でキー名を指定する
type Person struct {
    Name string `json:"name"`  // `Name`フィールドはJSONのキー名が`name`になる
}
  • フィールドが空の場合に、出力に含めたくない場合はキー名のあとに,omitemptyをつける。マーシャリング時(JSON -> Go構造体)の時だけ適用されるため、アンマーシャリング時にはomitemptyタグは無視され、JSONデータからすべてのフィールドが構造体フィールドに変換される
type Person struct {
    Name    string `json:"name"`
    Age     int    `json:"age"`
    Address string `json:"address,omitempty"` // Addressが空の場合JSON出力から除外される
}
  • キー名の前にハイフンをつけることで、マーシャリングの際にJSON出力から除外される。アンマーシャリング時にはハイフンは無視され、JSONデータに含まれているフィールドは対応する構造体フィールドに変換される(値はゼロ値が設定される)
type Person struct {
    Name  string `json:"name"`
    Email string `json:"-"` // EmailフィールドはJSON出力に含まれない
}

マーシャリングとアンマーシャリング

ここからは、具体的なコード例を交えてJSONのエンコードとデコードの方法を見ていきたいと思います。

マーシャリング(JSONエンコード)

Goの構造体型をJSON形式に変換するためMarchal関数を使います。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Address string `json:"address,omitempty"`
}

func main() {
	// Personインスタンスを作成
	p := Person{
		Name: "John Doe",
		Age:  30,
	}

	// PersonインスタンスをJSONに変換
	b, err := json.Marshal(p)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(b))
}

上記のコードを実行すると、以下のようなJSON出力が得られます。,omitemptyオプションを指定しているAddressフィールドは空であるため出力されていないことが分かります。

{
    "name": "John Doe",
    "age": 30
}

アンマーシャリング(JSONデコード)

JSON形式のデータをGoの構造体に変換するためUnmarshal関数を使用します。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"-"`
	Address string `json:"address,omitempty"`
}

func main() {
	// JSONデータ
	jsonData := `{"name":"John","age":0}`

	// Personインスタンスを生成
	var p Person

	// JSONデータをPersonインスタンスに変換
	err := json.Unmarshal([]byte(jsonData), &p)
	if err != nil {
		fmt.Println(err)
		return

	}

	fmt.Printf("%+v\n", p)
}

上記のコードを実行すると、以下のような出力が得られます。Ageフィールドにはハイフンを設定していますが、アンマーシャリングのため、対応するフィールドに変換されゼロ値が設定させています。Addressフィールドについては、JSONに対応するフィールドが存在しませんが、出力にはAddressフィールドが設定されていることが分かります。

{Name:John Age:0 Address:}

まとめ

この記事では、Go言語を使ってJSONデータと構造体の相互変換を行う方法について解説しました。標準ライブラリであるencoding/jsonパッケージを使用して、エンコード(マーシャリング)とデコード(アンマーシャリング)の基本的な使い方を説明しました。以下に主要なポイントをまとめます。

  • マーシャリング (Go構造体 -> JSON形式):
    • Marshal関数を使用して、Go構造体をJSON形式に変換する
    • 構造体タグにjson:"fieldname,omitempty"を付けることで、ゼロ値のフィールドをJSON出力から省略できる
    • json:"-"タグを付けたフィールドは、マーシャリングの際に常に出力から除外される
  • アンマーシャリング (JSON形式 -> Go構造体):
    • Unmarshal関数を使用して、JSONデータをGo構造体に変換する
    • omitemptyタグはアンマーシャリング時には無視され、JSONデータに含まれるすべてのフィールドが対応する構造体フィールドに変換される
    • json:"-"タグを付けたフィールドは、アンマーシャリング時には無視され、JSONデータに含まれるフィールドは対応する構造体フィールドに変換される(値はゼロ値が設定される)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0