У меня есть несколько структур, которые требуют пользовательской сортировки. Когда я тестировал, я использовал JSON и стандартный маршаллер JSON. Поскольку он не маршали неэкспортированные поля, мне нужно было написать пользовательскую функцию MarshalJSON, которая отлично работала. Когда я вызывал json.Marshal в родительской структуре, содержащей те, которые нуждались в настройке сортировки в качестве полей, он работал нормально.Обработка пользовательских BSON Marshaling (Golang & mgo)
Теперь мне нужно собрать все для 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 является Продуктом, он производит вывод, который я хочу, без потребности в шаблоне (не уверен в имени), где вы создаете структуру, которая является всего лишь клоном со всеми экспортируемыми полями.
На мой взгляд, используя встроенный метод, который я использовал, значительно упрощает API и останавливает у вас дополнительные структуры, которые загромождают вещи.
Я полагаю, тот факт, что валюты структура является объявлено с использованием невыполненных полей, является опечаткой? – SirDarius
Нет, это преднамеренно. Существует больше кода, чем то, что выше, и я большой сторонник использования геттеров/сеттеров, чтобы остановить программиста, чтобы он мог просто изменить то, что они хотят, не обращая внимания на неизменную бизнес-логику, плюс слой абстракции означает любое изменение позже по строке к внутренней работе моей структуры означает, что мне нужно изменить минимальный код. – leylandski
А также, если вы являетесь пользователем пакета 'shoppring/decimal', поля не экспортируются - поэтому в любом случае вам все равно придется определять пользовательский Getter/Setter, чтобы включить сериализацию/десериализацию, как показано в ответ. –