🌊

Go言語で構造体定義を動的に作成する

2023/10/20に公開

TL;DR

reflectパッケージを利用してコードから構造体を定義することができる。

背景

Goで構造体からJSONを生成するとき、omitemptyタグを利用すれば値がゼロ値のときキーを省略できる。
認可などの状況で、値がゼロ値でない場合でもキーを省略したい場合がある。
どう実現するのが正攻法なのかわからなかったので有識者は是非コメントで教えてください。
今回は構造体のフィールドを動的に制御することでJSONのキーを制御することを考えた。

コード

https://go.dev/play/p/z0RClGp9wvJ

package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

func main() {
	// Definition
	dynamicFields := []reflect.StructField{
		reflect.StructField{
			Name: "Name",
			Type: reflect.TypeOf(""),
			Tag:  `json:"foo"`,
		},
	}
	structDef := reflect.New(reflect.StructOf(dynamicFields))

	// New
	structVal := structDef.Elem()
	structVal.Field(0).SetString("gopher")

	// JSON
	v, _ := json.Marshal(structVal.Interface())
	fmt.Println(string(v))
}

補足

既存の構造体からフィールドを省略する方法ではなく、ゼロベースからフィールドを追加していく方式。
フィールド数が多くなれば多分きにいらなくなる。それはそのときまた考える。

Discussion