Unmarshal to a interface type

后端 未结 1 1719
没有蜡笔的小新
没有蜡笔的小新 2020-12-10 09:13

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

相关标签:
1条回答
  • 2020-12-10 09:55

    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)
    }
    
    0 讨论(0)
提交回复
热议问题