Go の JSON が警告なしに潰す null と欠落

結論 JSON の「キー欠落」「null」「[]」「0」を、Go の型は全部は区別できない。encoding/json は区別が消えてもエラーを返さない 書く側: nil スライスは null になる。*T に omitempty を付けると null を出せない。同じ階層に同じタグがあると両方消える。NaN が 1 つあると Marshal そのものが失敗する 読む側: キーは大文字小文字を無視して照合し、構造体に無いキーは捨てる。null はポインタ・スライス・map・interface 以外には何もしない。値型は 0 と欠落を、ポインタは null と欠落を区別できない 区別が契約なら、型に頼らず map[string]json.RawMessage でキー単位に見る。テストも構造体ではなく生の JSON で固定する 以下は Go 1.26.4 / testify v1.12.1 / go-playground/validator v10.30.5 で実測した。 前提: 区別を持てるのは Go の型の側だけ JSON の 1 項目は「キーが無い」「null」「空 ([] / "")」「ゼロ (0 / false)」「値あり」のどれかになる。 Go の値型が持てる状態は「ゼロ値」か「値あり」の 2 つで、ポインタ・スライス・map は nil の分だけ 1 つ増える。 JSON 側の状態を Go の型へ写すと、どこかの区別が消える。 ...

2026-10-01 ·  2026-10-01 · 5 分 · 1027 文字

Go言語omitemptyの罠:falseが保存できない

結論:omitemptyは便利だが罠がある omitemptyタグは空値を省略できて便利だが、falseや0が保存できなくなる罠がある。 特にboolean型で**「false」と「未設定」を区別したい場合は要注意**だ。 omitemptyとは 空値の場合にフィールドを省略するタグ。JSON/Firestoreへの保存時にデータサイズを削減できる。 type User struct { Name string `json:"name"` Email string `json:"email,omitempty"` // 空なら省略 } ⚠️ 最大の罠:「空」とみなされる値 以下の値は「空」として扱われ、omitempty付きフィールドから消える: 型 空とみなされる値 保存できない値の例 真偽値 false ❌ falseが保存不可 数値 0 ❌ 0が保存不可 文字列 "" ❌ 空文字列が保存不可 スライス/マップ nil または長さ0 ❌ 空配列が保存不可 ポインタ nil - time.Timeのゼロ値は、JSONでは「空」に当たらず消えない。下の「struct と time.Time は omitempty で消えない」を参照。 実例:boolean型の罠 問題のあるコード type Config struct { EnableFeature bool `firestore:"enableFeature,omitempty"` } config := Config{EnableFeature: false} // ❌ Firestoreに保存されない! // "enableFeature"フィールド自体が消える これでは「false」と「未設定」が区別できない。 ...

2025-10-27 ·  2026-10-03 · 2 分 · 372 文字