I have some code I\'ve been dumped with and am actually stumped - I\'ve worked with RPC and the JSON side of things before but I can\'t seem to get it to work over RPC when
All marshaling/unmarshaling has this problem.
You can marshal from an interface type variable, because the object exists locally, so the reflector knows the underlying type.
You cannot unmarshal to an interface type, because the reflector does not know which concrete type to give to a new instance to receive the marshaled data.
In some marshal/unmarshal frameworks we need additional information to help the reflector. For example, in Java Json(jackson), we use the JsonTypeInfo
annotation to specify the class type, refer to this.
For golang, you can implement the Unmarshaler interface for your own type yourself. Refer to How do I Unmarshal JSON?
// RawString is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawString string
// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawString) MarshalJSON() ([]byte, error) {
return []byte(*m), nil
}
// UnmarshalJSON sets *m to a copy of data.
func (m *RawString) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("RawString: UnmarshalJSON on nil pointer")
}
*m += RawString(data)
return nil
}
const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`
type A struct {
I int64
S RawString `sql:"type:json"`
}
func main() {
a := A{}
err := json.Unmarshal([]byte(data), &a)
if err != nil {
log.Fatal("Unmarshal failed", err)
}
fmt.Println("Done", a)
}