2016-07-20 3 views
1

Ich versuche zu arbeiten, um ein json Objekt in ein struct, aber integer Werte auf 0 gesetzt analysieren wird nicht funktionieren.Golang: Abstellungs/Marshal json mit int auf 0 gesetzt scheint nicht

q := []byte(`{"string":"this is a string", "integer": 0}`) 

type Test struct { 
    String string `json:"string,omitempty"` 
    Integer int `json:"integer,omitempty"` 
}  

var qq Test 
if err := json.Unmarshal(q, &qq); err != nil { 
    panic(err) 
} 

queryStr, err := json.Marshal(qq) 
if err != nil { 
    panic(err) 
} 
fmt.Println(string(queryStr)) 
// Output: {"string": "this is a string"} 

Wenn ich die Ganzzahl auf alles außer 0 setze, funktioniert das problemlos.

Auch wenn ich das Objekt unmarshale und das Integer-Feld auf 0 setze, entfernt das Marshalling das Feld "integer".

Warum? und wie kommt man damit klar?

EDIT:

von dem, was ich aus den Kommentaren sammeln, löst omitempty wenn der Wert 0 ist also jetzt das Verschwinden Sinn macht.

Ich Parsing JSON, Bearbeiten und Weiterleiten an einen anderen Dienst, so ist dies bedauerlich, vor allem, da Feld nicht vorhanden standardmäßig auf andere Werte als 0, und ich möchte nicht die Standardeinstellungen für die Downstream einspeisen müssen API.

Also gibt es eine Möglichkeit, leere Werte wegzulassen, aber 0 zu behalten?

oder leer auf etwas anderes ändern?

Muss ich 2 Strukturen haben: eine für die Eingabe und eine für die Ausgabe?

+4

Sie haben 'omitemperty', und 0 ist der leere Wert. – JimB

+0

Ich brauche omitemptpy, da ich das Feld nicht komplett haben kann, aber ich brauche auch den Wert 0. Also gibt es einen Weg um dies zu erreichen? – MrE

+0

Wenn das Feld nicht vorhanden ist, wird in dem Programm, in dem es verwendet wird, standardmäßig ein Wert verwendet, der nicht 0 ist. Also wird kein Feld standardmäßig 10, aber ich muss 0 setzen können. Gibt es eine Möglichkeit zu setzen ein Standardwert für ein Strukturfeld? – MrE

Antwort

9

Verwenden Sie einen Zeiger für die Felder, sodass der Nullwert des JSON-Typs vom fehlenden Wert unterschieden werden kann.

type Test struct { 
    String *string `json:"string,omitempty"` 
    Integer *int `json:"integer,omitempty"` 
} 

https://play.golang.org/p/yvYSHxubLy

+0

das scheint die Lösung zu sein ... Danke! – MrE

0

wie die docs sagt in https://golang.org/pkg/encoding/json/#Marshal

Struct Werte kodieren als JSON-Objekte. Jedes exportierte struct Feld wird Mitglied des Objekts, es sei denn

  • Feld des Tag „-“ oder
  • das Feld leer und sein Tag gibt die „omitempty“ -Option. Die leeren Werte sind false, 0, ein beliebiger Nullzeiger oder Schnittstellenwert und alle Arrays, Slices, Maps oder Strings der Länge Null. Der Standardschlüssel des Objekts string ist der Name des Strukturfelds, kann aber im Tag-Wert des Felds struct angegeben werden. Der Schlüssel "json" im Tag-Wert des Strukturfelds ist der Schlüsselname, gefolgt von einem optionalen Komma und Optionen.

so nicht, es sei denn, Sie Ihre eigenen Einweiser für Ihre Struktur Sinn von struct zu für Marshalling JSON nur

3

"omitempty" Tag macht implementieren. Es überspringt leere Werte, so dass sie nicht in JSON sind.Es hat keinerlei Auswirkungen auf das Unmarshalling. Verwenden Sie Zeiger, wenn Sie erkennen möchten, ob das Feld in JSON angegeben ist oder nicht. Wenn das Feld nicht angegeben ist, lautet der Zeigerwert null.