関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。忘れないうちにメモメモ。。。
JSONのエンコード・デコードは、よくやる作業ですが、デコード時に構造体側のフィールド定義が漏れてしまっていて、値が入っていないというミスをするときがあります。
その場合は、*json.Decoder.DisallowUnknownFields()
を呼んでおくと、救われるときがあったりします。
この呼び出しをしておくと、「JSON側に定義されているフィールドが、構造体側に存在しない場合にエラー」となります。
サンプル
package jsonop import ( "encoding/json" "errors" "io" "strings" "github.com/devlights/gomy/output" ) // DisallowUnknownFields は、*Decoder.DisallowUnknownFields のサンプルです。 // // # REFERENCES // - https://pkg.go.dev/encoding/json@go1.21.6#Decoder.DisallowUnknownFields func DisallowUnknownFields() error { const ( jsonValue = `{"id": 1, "name": "Test1", "age": 99}` ) type Val struct { Id int `json:"id"` Name string `json:"name"` } var ( stream = strings.NewReader(jsonValue) dec = json.NewDecoder(stream) ) // // 普通にデコード // // *json.Decoder.DisallowUnknownFields() を呼んでいないので // 存在しないJSONフィールドがあってもエラーにはならない。 // var ( v Val err error ) err = dec.Decode(&v) if err != nil && !errors.Is(err, io.EOF) { return err } output.Stdoutf("[Normal]", "%v\n", v) // // 不明なフィールドは許可しないよう設定 // // この場合の「不明なフィールド」というのは // "JSON側に存在しているフィールドが、受け側の構造体に存在しない場合" という意味。 // 構造体側に存在しているフィールドが、JSON側に存在しないのはエラーにならないので注意。 // // 今度は、ageというJSONフィールドに対応する構造体フィールドが存在しないのでエラーとなる。 // stream = strings.NewReader(jsonValue) dec = json.NewDecoder(stream) dec.DisallowUnknownFields() err = dec.Decode(&v) if err != nil && !errors.Is(err, io.EOF) { output.Stdoutf("[DisallowUnknownFields]", "%v(%T)", err, err) } return nil }
実行すると以下のようになります。
$ task task: [build] go build . task: [run] ./try-golang -onetime ENTER EXAMPLE NAME: json_disallow_unknown_fields [Name] "json_disallow_unknown_fields" [Normal] {1 Test1} [DisallowUnknownFields] json: unknown field "age"(*errors.errorString) [Elapsed] 158.11µs
参考情報
https://pkg.go.dev/encoding/json@go1.21.6#Decoder
https://pkg.go.dev/encoding/json@go1.21.6#Decoder.DisallowUnknownFields
try-golang/examples/basic/jsonop/disallow_unknown_fields.go at main · devlights/try-golang · GitHub
Goのおすすめ書籍
上の書籍の日本語版が下です。
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。