114

私はこのような構造体を持っています:

type Result struct {
    Data       MyStruct  `json:"data,omitempty"`
    Status     string    `json:"status,omitempty"`
    Reason     string    `json:"reason,omitempty"`
}

ただし、MyStruct のインスタンスが完全に空 (つまり、すべての値が既定値) の場合でも、次のようにシリアル化されています。

"data":{}

encoding/jsonドキュメントでは、「空の」フィールドが次のように指定されていることを知っています。

false、0、任意の nil ポインターまたはインターフェイス値、および任意の配列、スライス、マップ、または長さゼロの文字列

ただし、すべての空/デフォルト値を持つ構造体は考慮されていません。そのすべてのフィールドも でタグ付けされていますomitemptyが、これは効果がありません。

空の構造体であるフィールドをマーシャリングしないように JSON パッケージを取得するにはどうすればよいですか?

4

4 に答える 4

174

ドキュメントが言うように、「任意の nil ポインター」。-- 構造体をポインターにします。ポインタには明らかな「空の」値があります: nil.

修正 - structポインターフィールドを使用して型を定義します。

type Result struct {
    Data       *MyStruct `json:"data,omitempty"`
    Status     string    `json:"status,omitempty"`
    Reason     string    `json:"reason,omitempty"`
}

次に、次のような値:

result := Result{}

次のようにマーシャリングします。

{}

説明:*MyStructタイプ定義の に注意してください。JSON シリアライゼーションは、それがポインターであるかどうかを気にしません。これはランタイムの詳細です。したがって、構造体フィールドをポインターにすることは、コンパイルとランタイムにのみ影響します)。

フィールド タイプを から に変更する場合は、次のように、値を設定するために構造体値へのポインタが必要になることに注意してMyStructください*MyStruct

Data: &MyStruct{ /* values */ }
于 2013-08-06T19:09:33.480 に答える
10

Dataは初期化された構造体であるためencoding/json、構造体内のフィールドではなく即時値のみを参照するため、空とは見なされません。

nil残念ながら、から戻るjson.Marshalerことは現在機能しません:

func (_ MyStruct) MarshalJSON() ([]byte, error) {
    if empty {
        return nil, nil // unexpected end of JSON input
    }
    // ...
}

マーシャラーを与えることもできますがResult、努力する価値はありません。

唯一のオプションは、Matt が示唆するようにData、ポインタを作成して値を に設定することnilです。

于 2013-08-06T20:14:38.287 に答える