I have seen plenty of ways to marshal/unmarshal structs that only have unexported fields. But how can I do this with mixed fields?
Given a struct:
type Test struct {
fieldA string `json:"fieldA"`
FieldB int `json:"fieldB"`
FieldC string `json:"fieldC"`
}
How can I write MarshalJSON/UnmarshalJSON functions so that fieldA is transported along with FieldB and FieldC?
The following compiles, but then overflows the call stack when I run it. My guess is I am recursively marshalling the object, but I am not sure of how else to preserve both exported and unexported fields when encoding.
func (t *Test) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
*Test
FieldA string `json:"fieldA"`
}{
t,
t.fieldA,
})
}
func (t *Test) UnmarshalJSON(b []byte) error {
return json.Unmarshal(b, &t)
}
Is there a way to do this? Or should I re-think my data structures and maybe just export the field anyway?
Note: I'm aware I can do each field manually, but I'd like to avoid that if possible to make updating the code more manageable.
You can create a specific structure to handle the JSON serialization message: http://play.golang.org/p/d057T7qfVB
type Test struct {
fieldA string
FieldB int
FieldC string
}
type TestJSON struct {
FieldA string `json:"fieldA"`
FieldB int `json:"fieldB"`
FieldC string `json:"fieldC"`
}
func (t *Test) MarshalJSON() ([]byte, error) {
return json.Marshal(TestJSON{
t.fieldA,
t.FieldB,
t.FieldC,
})
}
func (t *Test) UnmarshalJSON(b []byte) error {
temp := &TestJSON{}
if err := json.Unmarshal(b, &temp); err != nil {
return err
}
t.fieldA = temp.FieldA
t.FieldB = temp.FieldB
t.FieldC = temp.FieldC
return nil
}