You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:50:14