0Pricing
Go Academy · レッスン

実践リフレクション:シリアライザー

reflectを使って、シンプルなJSON風シリアライザーを構築します。

「実践リフレクション:シリアライザー」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

カスタム JSON シリアライザーの概要

リフレクションを使ったカスタムシリアライザーの構築は、実践的なリフレクションの使い方を示します。構造体フィールドを反復処理し、タグを読み取り、値にアクセスして出力を構築します。これは encoding/json が内部で使用している方法と同じです。

構造体からマップへの変換

リフレクションを使って構造体を map[string]any に変換します:

func StructToMap(v any) map[string]any {
    t := reflect.TypeOf(v)
    val := reflect.ValueOf(v)
    result := make(map[string]any, t.NumField())
    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)
        if !f.IsExported() { continue }
        key := f.Tag.Get("json")
        if key == "" { key = f.Name }
        result[key] = val.Field(i).Interface()
    }
    return result
}

ポインターの処理

値を読み取る前に、ポインターフィールドをデリファレンスします:

fv := val.Field(i)
if fv.Kind() == reflect.Ptr {
    if fv.IsNil() { continue }
    fv = fv.Elem()
}

ネストされた構造体の処理

ネストされた構造体フィールドを再帰的に処理します:

if fv.Kind() == reflect.Struct {
    result[key] = StructToMap(fv.Interface())
    continue
}

omitempty のサポート

タグに "omitempty" が含まれている場合は、ゼロ値のフィールドをスキップします:

if strings.Contains(tag, "omitempty") && fv.IsZero() { continue }

マップから構造体への変換(デシリアライザー)

マップのキーをフィールドのタグと照合して、マップから構造体に値を設定します:

func MapToStruct(m map[string]any, dest any) {
    t := reflect.TypeOf(dest).Elem()
    v := reflect.ValueOf(dest).Elem()
    for i := 0; i < t.NumField(); i++ {
        key := t.Field(i).Tag.Get("json")
        if val, ok := m[key]; ok {
            v.Field(i).Set(reflect.ValueOf(val))
        }
    }
}

型変換

JSON から得られるマップの値は、数値の場合に float64 であることがよくあります。設定時に、対象フィールドの型に変換します:

if f.Type.Kind() == reflect.Int && reflect.TypeOf(val).Kind() == reflect.Float64 {
    v.Field(i).SetInt(int64(val.(float64)))
}

フィールドメタデータのキャッシュ

シリアライズを呼び出すたびにリフレクションを繰り返さないよう、フィールドとタグの対応を reflect.Type をキーとする sync.Map にキャッシュします。

コード生成という代替手段

パフォーマンスが重要な処理経路では、easyjson や ffjson などのツールで型専用のシリアライザーを生成します。これらは実行時のリフレクションを完全に回避します。

カスタムシリアライザーを構築する場面

カスタムシリアライザーは、JSON 以外の形式(BSON、Avro、CSV)、独自のエンコード規則、または厳しいパフォーマンス要件がある場合に役立ちます。ほとんどの用途では encoding/json で十分です。

シリアライザーのテスト

ラウンドトリップテスト:構造体をマップにシリアライズし、元に戻してデシリアライズした後、値が元の値と一致することをアサートします:

u := User{Name: "Alice", Age: 30}
m := StructToMap(u)
var u2 User
MapToStruct(m, &u2)
assert.Equal(t, u, u2)

クイックチェック

リフレクションベースのシリアライザーを構築する際、フィールドメタデータのキャッシュが重要なのはなぜですか?

まとめ:リフレクションベースのシリアライザー

重要なポイント:

  • NumField/Fieldでフィールドを反復処理し、Tag.Getでタグを読み取ります
  • ポインター、ネストされた構造体、ゼロ値を処理します
  • パフォーマンス向上のため、フィールドメタデータをsync.Mapにキャッシュします
  • 最高のスループットが必要な場合はコード生成を使用します

よくある質問

「実践リフレクション:シリアライザー」レッスンは無料ですか?

はい。「実践リフレクション:シリアライザー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「実践リフレクション:シリアライザー」で何を学びますか?

reflectを使って、シンプルなJSON風シリアライザーを構築します。 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「実践リフレクション:シリアライザー」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. reflect.Typeとreflect.Value
  2. 構造体フィールドとタグの調査
  3. 動的な関数呼び出し
  4. 実践リフレクション:シリアライザー
← Go Academyに戻る