ProgrammingバックエンドGo開発者

GoにおけるJSON(encoding/json)の扱い方:シリアル化の特徴、構造体のタグの特徴、マシュアルおよびアンマーシャル時のよくある問題と回避策は?

Hintsage AIアシスタントで面接を突破

回答。

Goでは、JSONマシュアルは標準でencoding/jsonパッケージを通じて実装されています。シリアライズできるのはエクスポートされた(大文字の)構造体のフィールドのみです。名前と処理の管理には構造体のタグを使用します:

type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
  • omitemptyはフィールドがゼロ値の場合に除外されます;
  • stringは値を文字列としてシリアライズし、たとえそれが数値でもです。

シリアル化の例:

user := User{ID: 1, Name: "オレグ"} b, _ := json.Marshal(user) fmt.Println(string(b)) // {"id":1,"name":"オレグ","age":"0"}

JSONの解析の例

var u User json.Unmarshal([]byte('{"id":2,"name":"イワン"}'), &u)

ひねりのある質問。

JSONでマシュアル時、非エクスポートされた(小文字の)構造体フィールドはどのようにシリアライズされますか?

正しい答え: それらは無視され、シリアライズにはエクスポートされた(大文字の)フィールドのみが参加します。これはAPIを妨げることがよくあります:

type Foo struct { bar int // シリアル化されません! }

このテーマの詳細を知らないことによる実際のエラーの例。


物語

バックエンドは不完全なJSONオブジェクトを返しました。必要なフィールドの一部が非エクスポート(小文字)であったためです。クライアントがこれらのフィールドを見ない理由を特定するのに数日かかりました。


物語

APIの応答にフィールドがomitemptyの構造を含んでいましたが、ゼロ値のスライスはnilであり、空のスライスではないため、時々空の値が返されました。クライアントは空の配列[]の代わりにnullを受け取り、解析時にクラッシュしました。


物語

プロジェクトでは、構造体に動的フィールドをmap[string]interface{}を通じて混ぜましたが、カスタムのUnmarshalJSONを実装することを忘れたため、データの一部がエラーなしに「失われる」ことがありました。クライアントのデータは失われ、手動でバックアップから復元されました。