Jak @chakrit wspomniano w komentarzu, nie można uzyskać to do pracy poprzez wdrożenie json.Marshalerna MyStructi wdrożenie funkcji rozrządowej zwyczaj JSON na każdej struktury, które zastosowań może być o wiele więcej pracy. To naprawdę zależy od twojego przypadku użycia, czy jest to warte dodatkowej pracy, czy też jesteś przygotowany do życia z pustymi strukturami w swoim JSON, ale oto wzorzec, którego używam, zastosowany do 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
}
Jeśli masz ogromne struktury z wieloma polami, może to stać się uciążliwe, zwłaszcza późniejsza zmiana implementacji struktury, ale oprócz przepisania całego jsonpakietu do własnych potrzeb (nie jest to dobry pomysł), jest to właściwie jedyny sposób, w jaki mogę wymyślić zrobiono to z jednoczesnym zachowaniem tam, gdzie nie ma wskaźnika MyStruct.
Nie musisz też używać struktur wbudowanych, możesz tworzyć nazwane. Używam jednak LiteIDE z uzupełnianiem kodu, więc wolę inline, aby uniknąć bałaganu.