mongo-go-driver中自定义UnmarshalBSON无法正确加载数据问题
自定义UnmarshalBSON后解析数据为空的问题解决
你这段代码的核心问题是传递给bson.Unmarshal的参数错误:aux本身已经是一个指向嵌套结构体的指针,再取地址传&aux,会让Unmarshal把数据解析到临时的二级指针指向的对象里,完全没写到你原本的d实例内存中,所以最终d的字段都是空值。
修正方案一(最简写法)
直接将原对象转换为别名类型指针,共享内存解析:
type MyData struct { X int `bson:"x"` Y string `bson:"y"` } func (d *MyData) UnmarshalBSON(data []byte) error { // 定义别名类型,不会继承原类型的UnmarshalBSON方法,避免递归 type Alias MyData // 直接把d转换为Alias指针,两者共享同一块内存 aux := (*Alias)(d) if err := bson.Unmarshal(data, aux); err != nil { return err } // 这里可以添加自定义的解析后处理逻辑 return nil }
修正方案二(保留嵌套结构体写法)
如果一定要用嵌套结构体的方式,只需修改Unmarshal的参数,传递aux而非&aux:
func (d *MyData) UnmarshalBSON(data []byte) error { type Alias MyData aux := &struct { *Alias }{ Alias: (*Alias)(d), } // 传递aux本身,它已经包含指向d的指针 if err := bson.Unmarshal(data, aux); err != nil { return err } return nil }
关键逻辑说明
- 定义
Alias作为MyData的类型别名,目的是避开原类型的UnmarshalBSON方法,防止Unmarshal时递归调用自定义方法导致死循环或解析异常。 - 确保解析的目标对象和原
d指向同一块内存,这样解析后的数据才能直接反映到d的字段中。
内容的提问来源于stack exchange,提问作者Joao Paulo Farias
相关产品推荐
相关产品推荐

