Open isayme opened 5 years ago
Go 语言本身是强类型, 这不利于处理联合体(union).
在使用 mgo 的过程中, 经常会遇到类似的场景: 某个字段的值可能是类型A, 也可能是类型B.
某个字段的值可能是类型A, 也可能是类型B.
为了达到上述的目的, 需要自定义 bson.Marshal & bson.Unmarsahl 方法: 实现 bson.Getter & bson.Setter interface
bson.Marshal
bson.Unmarsahl
bson.Getter
bson.Setter
完整的示例的代码: https://play.golang.org/p/ESDlrW353is
// 示例结构体 type T struct { ID string Elem Elem }
需求: 存储 T 类型字段到 mongo 时, 如果 ID 字段有值, 则存入 ID, 否则存入 Elem 字段.
ID
Elem
实现 bson.Getter interface, 自定义字段序列化.
// GetBSON bson marshal func (t T) GetBSON() (interface{}, error) { if t.ID != "" { return t.ID, nil } else { return t.Elem, nil } }
实现 bson.Setter interface, 自定义字段反序列化.
// SetBSON bson unmarshal func (t *T) SetBSON(raw bson.Raw) error { if err := raw.Unmarshal(&t.Elem); err == nil { return nil } return raw.Unmarshal(&t.ID) }
结构体 json 序列化后等价于序列化其中一种有效字段.
// MarshalJSON custom json.Unmarshal func (t T) MarshalJSON() ([]byte, error) { if t.ID != "" { return json.Marshal(t.ID) } else { return json.Marshal(t.Elem) } }
// UnmarshalJSON custom json.Marshal func (t *T) UnmarshalJSON(data []byte) error { if data[0] == '"' { return json.Unmarshal(data, &t.ID) } else { return json.Unmarshal(data, &t.Elem) } }
Go 语言本身是强类型, 这不利于处理联合体(union).
在使用 mgo 的过程中, 经常会遇到类似的场景:
某个字段的值可能是类型A, 也可能是类型B.
为了达到上述的目的, 需要自定义
bson.Marshal
&bson.Unmarsahl
方法: 实现bson.Getter
&bson.Setter
interface完整的示例的代码: https://play.golang.org/p/ESDlrW353is
自定义 bson.Marshal & bson.Unmarshal
需求: 存储 T 类型字段到 mongo 时, 如果
ID
字段有值, 则存入ID
, 否则存入Elem
字段.bson.Marshal: GetBSON
实现
bson.Getter
interface, 自定义字段序列化.bson.Unmarshal: SetBSON
实现
bson.Setter
interface, 自定义字段反序列化.自定义 json.Marshal & json.Unmarshal
结构体 json 序列化后等价于序列化其中一种有效字段.
json.Marshal: MarshalJSON
json.Unmarshal: UnmarshalJSON
参考资料