Como @chakrit mencionado en un comentario, usted no puede conseguir que esto funcione mediante la implementación json.Marshalerde 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 jsonpaquete 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 MyStructallí.
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.