Anpassen des JSON-Unmarshalings mit Reflection
In Go ist das Unmarshaling von JSON in eine Struktur ein unkomplizierter Prozess. Beim Umgang mit Feldern mit benutzerdefinierten Tags wie json:"some_field" reicht der standardmäßige Unmarshalling-Mechanismus jedoch möglicherweise nicht aus.
Ein Ansatz zur Bewältigung dieses Szenarios ist die Verwendung von Reflektion. Indem wir die Felder der Struktur mithilfe von Reflektion überprüfen, können wir prüfen, ob ein Feld ein bestimmtes Tag hat, und wenn ja, das Unmarshalling entsprechend handhaben.
In diesem speziellen Fall möchten wir sicherstellen, dass ein Feld mit dem JSON-Tag vorhanden ist unverändert in ein String-Feld entmarshallt. Dadurch können wir JSON-Objekte oder -Arrays innerhalb unserer Go-Struktur verarbeiten.
Beispielszenario
Berücksichtigen Sie die folgenden JSON-Daten und Go-Strukturen:
{
"I": 3,
"S": {
"phone": {
"sales": "2223334444"
}
}
}
type A struct {
I int64
S string `sql:"type:json"`
}
Unser Ziel ist es, das „S“-Feld als String zu entmarshalieren und dabei seine verschachtelte JSON-Struktur beizubehalten.
Lösung mit Reflection
Das Folgende Code zeigt, wie man dies mithilfe von Reflection erreicht:
func main() {
a := A{}
// Unmarshal the JSON data into a byte slice
var data []byte
// Iterate over the fields of the struct
typ := reflect.TypeOf(a)
val := reflect.ValueOf(a)
for i := 0; i Bei diesem Ansatz überprüfen wir manuell jedes Feld der Struktur mithilfe von Reflektion, um festzustellen, ob es das „json“-Tag hat. Wenn dies der Fall ist, entpacken wir die JSON-Daten als Zeichenfolge in das Feld.
Alternative Lösung mit benutzerdefiniertem Marshaler und Unmarshaler
Eine andere Option besteht darin, einen benutzerdefinierten Typ zu implementieren. wie RawString, das die Schnittstellen json.Marshaler und json.Unmarshaler implementiert. Dies ermöglicht mehr Flexibilität und Kontrolle über den Unmarshalling-Prozess.
Dieser Ansatz wird im folgenden Code demonstriert:
// RawString is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawString string
// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawString) MarshalJSON() ([]byte, error) {
return []byte(*m), nil
}
// UnmarshalJSON sets *m to a copy of data.
func (m *RawString) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("RawString: UnmarshalJSON on nil pointer")
}
*m = RawString(data)
return nil
}
const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`
type A struct {
I int64
S RawString `sql:"type:json"`
}
func main() {
a := A{}
err := json.Unmarshal([]byte(data), &a)
if err != nil {
log.Fatal("Unmarshal failed", err)
}
fmt.Println("Done", a)
}
Durch die Implementierung unseres eigenen Typs können wir den Unmarshalling-Prozess anpassen und die Notwendigkeit einer Reflexion vermeiden, was zu einer saubereren und effizienteren Lösung führt.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3