JSON-Schlüsselnamen in Kleinbuchstaben mit JSON Marshal in Go

175

Ich möchte das "encoding/json"Paket verwenden, um eine Struktur zu marshallen, die in einem der importierten Pakete meiner Anwendung deklariert ist.

Z.B.:

type T struct {
    Foo int
}

Da es importiert wird, beginnen alle verfügbaren (exportierten) Felder in der Struktur mit einem Großbuchstaben. Aber ich möchte Kleinbuchstaben haben:

out, err := json.Marshal(&T{Foo: 42})

wird darin enden, dass

{"Foo": 42}

aber ich möchte bekommen

{"foo": 42}

Ist es möglich, das Problem auf einfache Weise zu umgehen?

ANisus
quelle
5
@ Zippoxer: Ich würde sagen: Ein Schlüssel in einem Client / Server-Kommunikationsprotokoll, der streng auf Kleinbuchstaben definiert ist. Nun, in meinem Fall spielt es keine Rolle, da ich das Protokoll selbst definiert habe. Aber zumindest theoretisch? Aber ich weiß, dass ich hauptsächlich zu viel Zeit mit einem dummen kleinen Detail verbringe.
ANisus
Entschuldige dich nicht. Sie sind nicht der Dumme, die Sprache, die nicht die vollständige JSON-Spezifikation akzeptiert, ist die Dumme (obwohl das Problem wie unten leicht zu lösen ist).
Jehan
@ANisus: Ich habe Ihre Frage in Bezug auf Strukturschlüsselnamen falsch verstanden, nicht in Bezug auf JSON-Schlüsselnamen. Die Abstimmung wurde zurückgezogen.
Flimzy

Antworten:

265

Schauen Sie sich die Dokumente zur Codierung von / json.Marshal an . Es wird die Verwendung von Strukturfeld-Tags erläutert, um zu bestimmen, wie der generierte JSON formatiert wird.

Beispielsweise:

type T struct {
    FieldA int    `json:"field_a"`
    FieldB string `json:"field_b,omitempty"`
}

Dadurch wird JSON wie folgt generiert:

{
    "field_a": 1234,
    "field_b": "foobar"
}
jimt
quelle
8
Feld-Tags? Oh mein Gott. Ich habe diesen ganzen Teil bei der Suche in den Dokumenten verpasst. Ich suchte nach Flags, Funktionen oder anderen Einstellungen. Nun, das ist genau die Antwort, nach der ich gesucht habe! Und außerdem habe ich ein neues Go-Konzept zu lernen: Feld-Tags :)
ANisus
Sie sind sehr praktisch. Sie können zur Laufzeit über das reflectPaket darauf zugreifen .
Jimt
Ja, wenn ich mit Reflexion arbeite, sehe ich, wie wunderbar es sein kann, einem Feld Metadaten hinzuzufügen! Übrigens habe ich gerade die Antwort versucht. Klappt wunderbar.
ANisus
5
Ich habe gerade angefangen, die Go-Sprache zu verfluchen - wie dumm ist das, warum sollten sie die Felder mit Kleinbuchstaben im generierten JSON usw. usw. machen? Dann bin ich auf diesen Thread gestoßen und dachte "OMG, das ist brillant !!!". Ich bin sogar gesprungen und habe meiner Freundin erklärt, warum ich so aufgeregt bin: D Es ist so cool :)))
nyxz
11
Stellen Sie sicher, dass zwischen dem Doppelpunkt und dem ersten Anführungszeichen des Tags kein Leerzeichen steht! Verwenden Sie json:"some_tag"anstelle von json: "some_tag". Ich habe eine Weile davon gebissen.
David Morales
8

Sie können mit den Schlüsseln, die Sie exportieren möchten, eine eigene Struktur erstellen und ihnen die entsprechenden JSON-Tags für Kleinbuchstaben geben. Anschließend können Sie die gewünschte Struktur in Ihre kopieren, bevor Sie sie als JSON codieren. Oder wenn Sie sich nicht mit der Erstellung einer lokalen Struktur beschäftigen möchten, können Sie wahrscheinlich eine map[string]interface{}erstellen und diese codieren.

Lily Ballard
quelle
Das Dumme ist, dass das andere Paket (das die Typen enthält) tatsächlich auch mir gehört. Aber ja, ich habe wahrscheinlich blind darauf gestarrt, dass es eine Struktur sein muss. Die Verwendung von map[string]interface{}würde funktionieren, solange ich keine verschachtelten Objekte / Strukturen habe
ANisus
1
@ANisus: Oh, meine Antwort war darauf zurückzuführen, dass Sie nicht die Kontrolle über die Definition der Struktur haben. Jimts Antwort ist definitiv das, was Sie wollen.
Lily Ballard
Ja, mir war nicht klar, ob es sich um ein externes Paket handelt oder nicht. Ihre Antwort ist jedoch immer noch relevant und nützlich, wenn Sie die Definitionen nicht kontrollieren.
ANisus