自定义解组为一种类型而不是输入不同的类型
Custom unmarshall to a type than input out different type
我正在学习 Go,我有一个问题:
我有一个这样定义的 Info
类型:
type Info struct {
ID ID `json:"id,omitempty"`
DisplayName string `json:"display_name,omitempty"`
}
我创建了一个自定义 UnmarshallJSON
函数来解组此结构,因为作为输入我有:
- 一个
[]interface{}
在位置 [0] 一个 int 和 [1] 一个字符串
- A
boolean
总是等于 false
意味着该字段是 null
我希望当输入为 false
时,信息为零。
这是 UnmarshallJSON
函数
func (i *Info) UnmarshalJSON(data []byte) error {
var v []interface{}
if err := json.Unmarshal(data, &v); err != nil {
var v bool
if err = json.Unmarshal(data, &v); err != nil {
return err
}
return nil
}
i.ID = ID(v[0].(float64))
i.DisplayName = v[1].(string)
return nil
}
太丑了,想知道有没有更好的选择。
非常感谢。
首先,您应该对意外的类型和长度更加谨慎,以避免恐慌。然后您可以解组为 []json.RawMessage
以推迟元素的解组,直到您准备好。最后你应该提防你的无效 true
.
这是我的最大努力,请其他人随意编辑(here是一个游乐场):
func (i *Info) UnmarshalJSON(data []byte) error {
var raw interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
switch r := raw.(type) {
case []interface{}:
case bool:
if r {
return errors.New("unexpected true, must be array or false")
}
return nil
default:
return fmt.Errorf("unexpected type %T, must be array or false", r)
}
var v []json.RawMessage
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v) != 2 {
return fmt.Errorf("unexpected length %d, must be 2", len(v))
}
if err := json.Unmarshal(v[0], &i.ID); err != nil {
return err
}
if err := json.Unmarshal(v[1], &i.DisplayName); err != nil {
return err
}
return nil
}
我正在学习 Go,我有一个问题:
我有一个这样定义的 Info
类型:
type Info struct {
ID ID `json:"id,omitempty"`
DisplayName string `json:"display_name,omitempty"`
}
我创建了一个自定义 UnmarshallJSON
函数来解组此结构,因为作为输入我有:
- 一个
[]interface{}
在位置 [0] 一个 int 和 [1] 一个字符串 - A
boolean
总是等于false
意味着该字段是null
我希望当输入为 false
时,信息为零。
这是 UnmarshallJSON
函数
func (i *Info) UnmarshalJSON(data []byte) error {
var v []interface{}
if err := json.Unmarshal(data, &v); err != nil {
var v bool
if err = json.Unmarshal(data, &v); err != nil {
return err
}
return nil
}
i.ID = ID(v[0].(float64))
i.DisplayName = v[1].(string)
return nil
}
太丑了,想知道有没有更好的选择。 非常感谢。
首先,您应该对意外的类型和长度更加谨慎,以避免恐慌。然后您可以解组为 []json.RawMessage
以推迟元素的解组,直到您准备好。最后你应该提防你的无效 true
.
这是我的最大努力,请其他人随意编辑(here是一个游乐场):
func (i *Info) UnmarshalJSON(data []byte) error {
var raw interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
switch r := raw.(type) {
case []interface{}:
case bool:
if r {
return errors.New("unexpected true, must be array or false")
}
return nil
default:
return fmt.Errorf("unexpected type %T, must be array or false", r)
}
var v []json.RawMessage
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v) != 2 {
return fmt.Errorf("unexpected length %d, must be 2", len(v))
}
if err := json.Unmarshal(v[0], &i.ID); err != nil {
return err
}
if err := json.Unmarshal(v[1], &i.DisplayName); err != nil {
return err
}
return nil
}