@chakritがコメントで述べたように、に実装json.Marshaler
してもこれを機能させることはできませんMyStruct
。また、それを使用するすべての構造体にカスタムJSONマーシャリング関数を実装すると、さらに多くの作業が必要になる可能性があります。追加の作業に値するかどうか、またはJSONで空の構造体を使用する準備ができているかどうかは、ユースケースによって異なりますが、私が使用するパターンはResult
次のとおりです。
type Result struct {
Data MyStruct
Status string
Reason string
}
func (r Result) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Data *MyStruct `json:"data,omitempty"`
Status string `json:"status,omitempty"`
Reason string `json:"reason,omitempty"`
}{
Data: &r.Data,
Status: r.Status,
Reason: r.Reason,
})
}
func (r *Result) UnmarshalJSON(b []byte) error {
decoded := new(struct {
Data *MyStruct `json:"data,omitempty"`
Status string `json:"status,omitempty"`
Reason string `json:"reason,omitempty"`
})
err := json.Unmarshal(b, decoded)
if err == nil {
r.Data = decoded.Data
r.Status = decoded.Status
r.Reason = decoded.Reason
}
return err
}
多くのフィールドを持つ巨大な構造体がある場合、これは面倒になる可能性があります。特に、後で構造体の実装を変更しjson
ますが、ニーズに合わせてパッケージ全体を書き直すことはできません(良い考えではありません)。これは、私が考えることができる唯一の方法です。これは、非ポインターMyStruct
をそこに保持したまま実行されます。
また、インライン構造体を使用する必要はなく、名前付きの構造体を作成できます。ただし、コード補完でLiteIDEを使用しているので、混乱を避けるためにインラインを使用します。