问题描述
我有一些需要自定义编组的结构。当我测试时,我使用JSON和标准的JSON编组器。由于它不编码未导出的字段,因此我需要编写一个自定义的MarshalJSON函数,该函数完美运行。当我在包含那些需要自定义编组的字段的父结构体上调用json.Marshal时,它运行正常。
I have a number of structs that require custom marshalling. When I was testing I was using JSON and the standard JSON marshaller. As it doesn't marshal unexported fields, I needed to write a custom MarshalJSON function, which worked perfectly. When I called json.Marshal on the parent struct containing the ones that needed custom marshalling as fields, it worked fine.
现在我需要为一些MongoDB编组一切到BSON工作,而且我找不到有关如何编写自定义BSON编组的任何文档。任何人都可以告诉我如何为我在下面演示的BSON / mgo做同样的事情?
Now I need to marshal everything to BSON for some MongoDB work, and I can't find any documentation about how to write custom BSON marshalling. Can anyone tell me how to do the equivalent for BSON/mgo for what I've demonstrated below?
currency.go (重要部分)
currency.go (the important parts)
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 (同样,只是相关的部分)
product.go (again, just the relevant parts)
type Product struct {
Name string
Code string
Price currency.Currency
}
当我调用json.Marshal(p),其中p是一个Product时,它会生成我想要的输出,而不需要该模式(不确定名称)在哪里创建一个结构,它只是一个包含所有导出在我看来,使用我使用的内联方法大大简化了API,并且阻止了额外的结构混乱。
When I call json.Marshal(p) where p is a Product, it produces the output I want without the need for the pattern (not sure of the name) where you create a struct which is just a clone with all exported fields.
$ b
推荐答案
自定义bson编组/解组以几乎相同的方式工作,您必须实施和接口
Custom bson Marshalling/Unmarshalling works nearly the same way, you have to implement the Getter and Setter interfaces respectively
类似这样的东西应该可以工作:
Something like this should work :
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,
}
}
// 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
}
}
这篇关于处理定制BSON Marshaling(Golang& mgo)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!