Như @chakrit đã đề cập trong một nhận xét, bạn không thể làm cho điều này hoạt động bằng cách triển khai json.Marshaler
trên MyStruct
và việc triển khai một chức năng điều phối JSON tùy chỉnh trên mọi cấu trúc sử dụng nó có thể tốn nhiều công sức hơn. Nó thực sự phụ thuộc vào trường hợp sử dụng của bạn về việc liệu nó có đáng để làm thêm hay không hoặc liệu bạn có sẵn sàng sống với các cấu trúc trống trong JSON của mình hay không, nhưng đây là mẫu tôi sử dụng áp dụng cho 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
}
Nếu bạn có cấu trúc khổng lồ với nhiều trường, điều này có thể trở nên tẻ nhạt, đặc biệt là việc thay đổi cách triển khai của cấu trúc sau này, nhưng thiếu việc viết lại toàn bộ json
gói cho phù hợp với nhu cầu của bạn (không phải là một ý kiến hay), đây là cách duy nhất tôi có thể nghĩ đến điều này được thực hiện trong khi vẫn giữ một con trỏ không MyStruct
ở đó.
Ngoài ra, bạn không cần phải sử dụng cấu trúc nội dòng, bạn có thể tạo những cấu trúc được đặt tên. Tuy nhiên, tôi sử dụng LiteIDE với mã hoàn thành, vì vậy tôi thích nội dòng hơn để tránh lộn xộn.