Como @chakrit mencionado en un comentario, usted no puede conseguir que esto funcione mediante la implementación json.Marshaler
de MyStruct
, y la implementación de una función de clasificación JSON personalizado en cada estructura que los usos que pueden ser mucho más trabajo. Realmente depende de su caso de uso en cuanto a si vale la pena el trabajo adicional o si está preparado para vivir con estructuras vacías en su JSON, pero aquí está el patrón que uso aplicado a 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
}
Si tiene estructuras enormes con muchos campos, esto puede volverse tedioso, especialmente cambiar la implementación de una estructura más adelante, pero a menos que vuelva a escribir todo el json
paquete para satisfacer sus necesidades (no es una buena idea), esta es prácticamente la única forma en que puedo pensar en obtener esto se hace mientras se mantiene un no puntero MyStruct
allí.
Además, no tiene que usar estructuras en línea, puede crear estructuras con nombre. Sin embargo, uso LiteIDE con finalización de código, por lo que prefiero en línea para evitar el desorden.