为了账号安全,请及时绑定邮箱和手机立即绑定

处理自定义 BSON 编组

处理自定义 BSON 编组

Go
慕码人8056858 2021-10-18 10:25:24
我有许多需要自定义编组的结构。当我进行测试时,我使用的是 JSON 和标准的 JSON 编组器。由于它不封送未导出的字段,我需要编写一个自定义的 MarshalJSON 函数,该函数运行良好。当我在包含需要自定义编组作为字段的父结构上调用 json.Marshal 时,它工作正常。现在我需要将所有内容编组到 BSON 以进行一些 MongoDB 工作,但我找不到任何有关如何编写自定义 BSON 编组的文档。谁能告诉我如何为我在下面演示的 BSON/mgo 做等效的事情?currency.go(重要部分)type Currency struct {    value        decimal.Decimal //The actual value of the currency.    currencyCode string          //The ISO currency code.}/*MarshalJSON implements json.Marshaller.*/func (c Currency) MarshalJSON() ([]byte, error) {    f, _ := c.Value().Float64()    return json.Marshal(struct {        Value        float64 `json:"value" bson:"value"`        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`    }{        Value:        f,        CurrencyCode: c.CurrencyCode(),    })}/*UnmarshalJSON implements json.Unmarshaller.*/func (c *Currency) UnmarshalJSON(b []byte) error {    decoded := new(struct {        Value        float64 `json:"value" bson:"value"`        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`    })    jsonErr := json.Unmarshal(b, decoded)    if jsonErr == nil {        c.value = decimal.NewFromFloat(decoded.Value)        c.currencyCode = decoded.CurrencyCode        return nil    } else {        return jsonErr    }}product.go(同样,只是相关部分)type Product struct {    Name  string    Code  string    Price currency.Currency}当我调用 json.Marshal(p) 其中 p 是产品时,它会生成我想要的输出,而无需模式(不确定名称),您可以在其中创建一个结构,该结构只是具有所有导出字段的克隆。在我看来,使用我使用过的内联方法大大简化了 API,并防止您有额外的结构使事情变得混乱。
查看完整描述

1 回答

?
呼唤远方

TA贡献1856条经验 获得超11个赞

自定义 bson 编组/解组的工作方式几乎相同,您必须分别实现Getter和Setter接口


这样的事情应该工作:


type Currency struct {

    value        decimal.Decimal //The actual value of the currency.

    currencyCode string          //The ISO currency code.

}


// GetBSON implements bson.Getter.

func (c Currency) GetBSON() (interface{}, error) {

    f := c.Value().Float64()

    return struct {

        Value        float64 `json:"value" bson:"value"`

        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`

    }{

        Value:        f,

        CurrencyCode: c.currencyCode,

    }, nil

}


// SetBSON implements bson.Setter.

func (c *Currency) SetBSON(raw bson.Raw) error {


    decoded := new(struct {

        Value        float64 `json:"value" bson:"value"`

        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`

    })


    bsonErr := raw.Unmarshal(decoded)


    if bsonErr == nil {

        c.value = decimal.NewFromFloat(decoded.Value)

        c.currencyCode = decoded.CurrencyCode

        return nil

    } else {

        return bsonErr

    }

}


查看完整回答
反对 回复 2021-10-18
  • 1 回答
  • 0 关注
  • 153 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信