Mam wiele struktur, które wymagają niestandardowego zestawiania. Kiedy testowałem, korzystałem z JSON-a i standardowego koordynatora JSON. Ponieważ nie zajmuje się niezbadanymi polami, musiałem napisać niestandardową funkcję MarshalJSON, która działała idealnie. Kiedy zadzwoniłem do json.Marshal na strukturę nadrzędną zawierającą te, które wymagały niestandardowych ustawień jako pól, działało dobrze.Praca z niestandardowym BSON Marshaling (Golang & mgo)
Teraz potrzebuję zebrać wszystko do BSON dla niektórych prac MongoDB, i nie mogę znaleźć żadnej dokumentacji o tym, jak napisać niestandardowy rozkaz BSON. Czy ktoś może mi powiedzieć, jak zrobić ekwiwalent dla BSON/mgo za to, co pokazałem poniżej?
currency.go (istotne części)
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 (ponownie, tylko odpowiednie części)
type Product struct {
Name string
Code string
Price currency.Currency
}
Kiedy zadzwonić json.Marshal (p) gdzie p jest produktem, produkuje dane wyjściowe, które chcę, bez potrzeby stosowania wzorca (nie jestem pewien nazwy), w którym tworzysz strukturę, która jest po prostu klonem ze wszystkimi wyeksportowanymi polami.
Moim zdaniem zastosowanie metody inline, której używałem, znacznie upraszcza interfejs API i zatrzymuje dodatkowe struktury, które powodują problemy.
Przypuszczam fakt, że struktura walutą jest zadeklarowane użycie nieodportowanych pól to literówka? – SirDarius
Nie, to celowe. Jest więcej kodu niż to, co powyżej i jestem wielkim zwolennikiem używania getters/setters, aby zatrzymać programistę, który potrafi zmienić to, co chce, bez względu na niezmienną logikę biznesową, a warstwa abstrakcji oznacza każdą zmianę później w dół do wewnętrznego działania mojej struktury oznacza, że muszę zmienić minimalną ilość kodu. – leylandski
A także, jeśli jesteś użytkownikiem pakietu 'shopspring/decimal', pola nie są eksportowane - więc w obu przypadkach będziesz musiał zdefiniować niestandardowy program Getter/Setter, aby umożliwić serializację/deserialization, jak pokazano w odpowiedź. –