KDOC 712: Goのjson.Unmarshalは構造体にないキーを黙って捨てる
この文書のステータス
- 作成
- 2026-10-18 貴島
- レビュー
- 2026-10-18 貴島
概要
Goの json.Unmarshal は、JSONに構造体のフィールドと対応しないキーがあっても、エラーにせず黙って捨てる。キーの綴りを間違えても気づけない。検知したいときは json.Decoder の DisallowUnknownFields を使う。
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type User struct {
Name string
}
func main() {
data := []byte(`{"Name": "a", "Age": 20}`)
var u1 User
err := json.Unmarshal(data, &u1)
fmt.Printf("Unmarshal: %+v, err: %v\n", u1, err)
var u2 User
dec := json.NewDecoder(bytes.NewReader(data))
dec.DisallowUnknownFields()
err = dec.Decode(&u2)
fmt.Printf("DisallowUnknownFields: %+v, err: %v\n", u2, err)
}
Unmarshal: {Name:a}, err: <nil>
DisallowUnknownFields: {Name:a}, err: json: unknown field "Age"
go version
go doc encoding/json | grep -A2 'unknown keys in the JSON object'
go version go1.26.7 linux/amd64
- When parsing a JSON object into a Go struct, unknown keys in the JSON object
are ignored (unless a Decoder is used and Decoder.DisallowUnknownFields has
been called).
関連
抽象。
- 想定に合わない入力をエラーにせず黙って捨てるので、誤りに気づけない
関連。
- 共通: KDOC 95: なぜjson.Unmarshalの引数はバイト列なのか。同じ
json.Unmarshalの話題 - 補足: KDOC 444: BurntSushi/tomlのUndecoded()で未知のキー混入を検出できる。未知のキーを検証するべき理由と、TOMLで検証する方法を書いている
- 類似: KDOC 690: Railsのモデルのバリデーションは既存のレコードを検査しない。どちらも一見検査されるように見えるが検査されてない
- 共通: KDOC 693: RailsのBooleanのcastは文字列の“0”や“f”もfalseにする。どちらも想定外の入力をエラーにしない
- 類似: KDOC 708: Rubyのlambdaは引数の数を検査するがprocはしない。想定に合わない入力を厳しくチェックするか寛容に進めるかの違い、という点で同じ