Jak @chakrit wspomniano w komentarzu, nie można uzyskać to do pracy poprzez wdrożenie json.Marshaler
na MyStruct
i 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 json
pakietu 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.