Umgang mit von Benutzerdefinierten BSON-Marshalling

Habe ich eine Reihe von Strukturen, die erfordern benutzerdefinierte marshalling. Wenn ich testen war ich mit JSON und die standard-JSON-marshaller. Da es nicht Marschall unexported Felder, brauchte ich zum schreiben eines benutzerdefinierten MarshalJSON Funktion, die perfekt funktioniert. Als ich json.Marschall auf der übergeordneten struct enthält diejenigen, die benötigten benutzerdefinierten marshalling als Felder, es funktionierte.

Nun muss ich Marschall alles zu BSON für einige MongoDB arbeiten, und ich finde keine Dokumentation darüber, wie das schreiben eines benutzerdefinierten BSON-marshalling. Kann mir jemand sagen, wie machen Sie das gleiche für BSON/mgo für das, was ich habe unten gezeigt?

Währung.gehen (die wichtigen Teile)

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
    }
}

Produkt.gehen (wiederum nur die relevanten Teile)

type Product struct {
    Name  string
    Code  string
    Price currency.Currency
}

Mir beim Aufruf von json.Marschall(p), wobei p ist ein Produkt, erzeugt es die Ausgabe, die ich will, ohne die Notwendigkeit für das Muster (nicht sicher über den Namen), wo Sie ein struct, das ist nur ein Klon mit allen exportierten Felder.

Meiner Meinung nach mit der inline-Methode, die ich verwendet habe, vereinfacht die API und hält Sie mit extra-Strukturen, die Unordnung die Dinge.

  • Ich nehme an, die Tatsache, dass die Währung struct deklariert ist, mit unexported Felder ein Tippfehler ?
  • Nein, es ist beabsichtigt. Es ist mehr code als das, was ist oben und ich bin ein großer Verfechter der Verwendung von Getter/setter zu stoppen, die Programmierer können nur ändern, was Sie wollen, ohne Rücksicht auf unveränderlich business-Logik, plus die Ebene der Abstraktion ist jede Veränderung, später die Linie nach unten, um das Innenleben von mein struct heißt, ich habe zu ändern, eine minimale Menge an code.
  • Und auch, wenn Sie einen Benutzer von der shopspring/decimal Paket, die Felder werden nicht exportiert – also in jedem Fall, Sie wäre noch zu definieren, ein custom Getter/Setter zu aktivieren serialisieren/deserialisation, wie gezeigt, in der Antwort.
InformationsquelleAutor leylandski | 2015-06-17
Schreibe einen Kommentar