GolangとJSON: MarshalとArrayの活用

By quonta 4月 16, 2024

Go言語のJSONパッケージとMarshalerとUnmarshaler

Go言語では、JSON形式のデータを扱うための機能が標準パッケージの一部として提供されています。その中心にあるのが encoding/json パッケージです。

このパッケージは、Goのデータ構造をJSONに変換(マーシャリング)したり、JSONをGoのデータ構造に変換(アンマーシャリング)したりするための関数や型を提供しています。

MarshalerとUnmarshaler

MarshalerUnmarshaler は、それぞれJSONへのマーシャリングとJSONからのアンマーシャリングをカスタマイズするためのインターフェースです。

type Marshaler interface {
    MarshalJSON() ([]byte, error)
}

type Unmarshaler interface {
    UnmarshalJSON([]byte) error
}

これらのインターフェースを実装することで、特定の型に対するJSONの変換方法を自由に定義することができます。これにより、標準の変換ルールだけでは対応できない複雑なケースにも対応することが可能になります。

次のセクションでは、これらのインターフェースを活用した具体的な例を見ていきましょう。

構造体のフィールドを指定の形式でMarshal, Unmarshalする

Go言語では、構造体のフィールドをJSONのキーとしてマーシャリングしたり、JSONのキーから構造体のフィールドにアンマーシャリングしたりする際に、フィールドタグを使用して変換の挙動を制御することができます。

フィールドタグの基本

Goの構造体では、フィールド宣言の後にバッククォート()で囲まれた文字列を書くことで、そのフィールドに対する追加の情報(フィールドタグ)を指定することができます。encoding/json` パッケージでは、このフィールドタグを利用してJSONのキー名を制御します。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

この例では、Person 構造体の Name フィールドはJSONでは name キーとして表現され、Age フィールドは age キーとして表現されます。

フィールドタグの応用

フィールドタグでは、さらに詳細な制御も可能です。例えば、JSONに存在しないキーに対応するフィールドを省略したり、逆にフィールドがゼロ値の場合にJSONからそのキーを省略したりすることができます。

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

この例では、Age フィールドに omitempty オプションが指定されています。これにより、Age フィールドがゼロ値(この場合は0)のときには、JSONから age キーが省略されます。

次のセクションでは、配列やスライスのJSON変換について見ていきましょう。

配列やスライスのJSON変換

Go言語では、配列やスライスもJSONとして表現することができます。これらの型は、JSONの配列としてマーシャリングされ、逆にJSONの配列はGoの配列やスライスとしてアンマーシャリングされます。

配列とスライスのマーシャリング

配列やスライスをJSONにマーシャリングするには、json.Marshal 関数を使用します。

nums := []int{1, 2, 3, 4, 5}
jsonBytes, err := json.Marshal(nums)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(jsonBytes))  // Output: [1,2,3,4,5]

この例では、整数のスライスがJSONの配列に変換されています。

配列とスライスのアンマーシャリング

逆に、JSONの配列をGoの配列やスライスにアンマーシャリングするには、json.Unmarshal 関数を使用します。

jsonStr := "[1,2,3,4,5]"
var nums []int
err := json.Unmarshal([]byte(jsonStr), &nums)
if err != nil {
    log.Fatal(err)
}
fmt.Println(nums)  // Output: [1 2 3 4 5]

この例では、JSONの配列がGoの整数のスライスに変換されています。

次のセクションでは、より複雑なJSONと構造体の変換について見ていきましょう。

複雑なJSON↔構造体の変換

Go言語では、複雑なJSONと構造体の変換も可能です。具体的には、ネストしたJSONや、キーが動的に変わるようなJSONも扱うことができます。

ネストしたJSONの変換

ネストしたJSONは、ネストした構造体に変換することができます。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    Address struct {
        Street string `json:"street"`
        City   string `json:"city"`
    } `json:"address"`
}

この例では、Address フィールドがネストした構造体として定義されています。これにより、以下のようなJSONを扱うことができます。

{
    "name": "John Doe",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown"
    }
}

動的なキーの変換

キーが動的に変わるようなJSONは、map[string]T 型(Tは任意の型)に変換することができます。

var m map[string]int
jsonStr := `{"apple": 1, "banana": 2, "cherry": 3}`
err := json.Unmarshal([]byte(jsonStr), &m)
if err != nil {
    log.Fatal(err)
}
fmt.Println(m)  // Output: map[apple:1 banana:2 cherry:3]

この例では、フルーツの名前をキーとし、その数を値とするJSONを map[string]int 型に変換しています。

以上が、Go言語での複雑なJSON↔構造体の変換についての基本的な説明です。次のセクションでは、独自の変換方式の定義と利用について見ていきましょう。

独自の変換方式の定義と利用

Go言語では、MarshalerUnmarshaler インターフェースを実装することで、独自のJSON変換方式を定義し、利用することができます。

Marshalerの実装

Marshaler インターフェースは、MarshalJSON() ([]byte, error) メソッドを要求します。このメソッドを実装することで、型のJSONへのマーシャリング方法をカスタマイズできます。

type MyInt int

func (m MyInt) MarshalJSON() ([]byte, error) {
    return []byte(fmt.Sprintf("\"%d\"", m)), nil
}

この例では、MyInt 型が Marshaler インターフェースを実装しています。その結果、MyInt 型の値はJSONでは文字列として表現されます。

Unmarshalerの実装

逆に、Unmarshaler インターフェースは、UnmarshalJSON([]byte) error メソッドを要求します。このメソッドを実装することで、JSONからのアンマーシャリング方法をカスタマイズできます。

func (m *MyInt) UnmarshalJSON(data []byte) error {
    var s string
    if err := json.Unmarshal(data, &s); err != nil {
        return err
    }
    i, err := strconv.Atoi(s)
    if err != nil {
        return err
    }
    *m = MyInt(i)
    return nil
}

この例では、MyInt 型が Unmarshaler インターフェースを実装しています。その結果、JSONの文字列から MyInt 型の値を生成することができます。

以上が、Go言語での独自の変換方式の定義と利用についての基本的な説明です。これらの技術を活用することで、様々な形式のJSONデータを効率的に扱うことが可能になります。これらの知識を活かして、Go言語でのJSONの扱い方をマスターしましょう!

By quonta

Related Post

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です