Ich habe eine Struktur wie diese:
type Result struct {
Data MyStruct `json:"data,omitempty"`
Status string `json:"status,omitempty"`
Reason string `json:"reason,omitempty"`
}
Aber selbst wenn die Instanz von MyStruct vollständig leer ist (dh alle Werte sind Standardwerte), wird sie wie folgt serialisiert:
"data":{}
Ich weiß, dass die Kodierungs- / JSON- Dokumente angeben, dass "leere" Felder sind:
false, 0, ein beliebiger Nullzeiger oder Schnittstellenwert sowie ein beliebiges Array, Slice, Map oder String der Länge Null
aber ohne Berücksichtigung einer Struktur mit allen leeren / Standardwerten. Alle Felder sind ebenfalls mit gekennzeichnet omitempty
, dies hat jedoch keine Auswirkung.
Wie kann ich das JSON-Paket dazu bringen , mein Feld, das eine leere Struktur ist , nicht zu marshallen?
&MyStruct{ /* values */ }
als Nullzeiger zählt? Der Wert ist nicht Null.Wie @chakrit in einem Kommentar erwähnt, können Sie diese an der Arbeit nicht erhalten durch die Umsetzung
json.Marshaler
aufMyStruct
, und auf jeder Struktur eine benutzerdefinierten JSON Rangier Funktion implementiert , dass Verwendungen es viel mehr Arbeit sein können. Es hängt wirklich von Ihrem Anwendungsfall ab, ob sich die zusätzliche Arbeit lohnt oder ob Sie bereit sind, mit leeren Strukturen in Ihrem JSON zu leben, aber hier ist das Muster, das ich verwendeResult
:Wenn Sie große Strukturen mit vielen Feldern haben, kann dies mühsam werden, insbesondere wenn Sie die Implementierung einer Struktur später ändern. Wenn Sie jedoch
json
nicht das gesamte Paket neu schreiben , um es Ihren Anforderungen anzupassen (keine gute Idee), ist dies so ziemlich der einzige Weg, den ich mir vorstellen kann Dies geschah, während immer noch ein Nicht-ZeigerMyStruct
drin blieb.Außerdem müssen Sie keine Inline-Strukturen verwenden, sondern können benannte erstellen. Ich verwende LiteIDE jedoch mit Code-Vervollständigung, daher bevorzuge ich Inline, um Unordnung zu vermeiden.
quelle
Data
ist eine initialisierte Struktur, daher wird sie nicht als leer betrachtet, daencoding/json
nur der unmittelbare Wert und nicht die Felder in der Struktur betrachtet werden.Leider funktioniert die Rückkehr
nil
vonjson.Marhsler
derzeit nicht:Sie könnten auch
Result
einen Marschall geben , aber die Mühe lohnt sich nicht.Die einzige Möglichkeit, wie Matt vorschlägt, besteht darin,
Data
einen Zeiger zu erstellen und den Wert auf zu setzennil
.quelle
encoding/json
nicht überprüft werden können. Es wäre nicht sehr effizient, ja. Aber es ist sicherlich nicht unmöglich.json.Marshaler
von Fall zu Fall erfolgen.MyStruct
es leer ist oder nicht, indem einjson.Marshaler
on onMyStruct
selbst implementiert wird . Beweis: play.golang.org/p/UEC8A3JGvxjson.Marshaler
den enthaltenenResult
Typ selbst implementieren , was sehr unpraktisch sein könnte.Es gibt einen hervorragenden Golang- Vorschlag für diese Funktion, der seit über 4 Jahren aktiv ist. Daher kann an dieser Stelle davon ausgegangen werden, dass sie nicht in Kürze in die Standardbibliothek aufgenommen wird. Wie @Matt hervorhob, besteht der traditionelle Ansatz darin, die Strukturen in Zeiger in Strukturen umzuwandeln . Wenn dieser Ansatz nicht durchführbar (oder unpraktisch) ist, besteht eine Alternative darin, einen alternativen JSON-Encoder zu verwenden, der das Weglassen von Nullwertstrukturen unterstützt .
Ich habe einen Spiegel der Golang json-Bibliothek ( clarketm / json ) erstellt, der zusätzlich unterstützt, dass beim Anwenden des
omitempty
Tags Nullwertstrukturen weggelassen werden . Diese Bibliothek erkennt die Nullheit auf ähnliche Weise wie der beliebte YAML-Encoder go-yaml, indem sie die öffentlichen Strukturfelder rekursiv überprüft .z.B
quelle