Personnalisation de la désorganisation de JSON avec Reflection
Dans Go, la désorganisation de JSON dans une structure est un processus simple. Cependant, lorsqu'il s'agit de champs comportant des balises personnalisées, telles que json:"some_field", le mécanisme de démarshalling standard peut ne pas suffire.
Une approche pour gérer ce scénario consiste à utiliser la réflexion. En inspectant les champs de la structure à l'aide de la réflexion, nous pouvons vérifier si un champ a une balise spécifique et si c'est le cas, gérer sa désorganisation en conséquence.
Dans ce cas particulier, nous voulons nous assurer qu'un champ avec la balise json est non organisé dans un champ de chaîne tel quel. Cela nous permet de gérer des objets ou des tableaux JSON dans notre structure Go.
Exemple de scénario
Considérez les données JSON et la structure Go suivantes :
<code class="json">{ "I": 3, "S": { "phone": { "sales": "2223334444" } } }</code>
<code class="go">type A struct { I int64 S string `sql:"type:json"` }</code>
Notre objectif est de désorganiser le champ « S » sous forme de chaîne, en préservant sa structure JSON imbriquée.
Solution utilisant la réflexion
Le code suivant démontre comment y parvenir en utilisant la réflexion :
<code class="go">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 < typ.NumField(); i++ { f := typ.Field(i) // Check if the field has a "json" tag if f.Tag.Get("json") == "" { continue } // Retrieve the field value fv := val.Field(i) // Unmarshall the JSON data into the field as a string if err := json.Unmarshal(data, &fv); err != nil { log.Fatal(err) } } fmt.Println(a) }</code>
Dans cette approche, nous inspectons manuellement chaque champ de la structure en utilisant la réflexion pour déterminer s'il possède la balise "json". Si tel est le cas, nous décomposons les données JSON dans le champ sous forme de chaîne.
Solution alternative avec Custom Marshaler et Unmarshaler
Une autre option consiste à implémenter un type personnalisé, comme RawString, qui implémente les interfaces json.Marshaler et json.Unmarshaler. Cela permet plus de flexibilité et de contrôle sur le processus de désorganisation.
Cette approche est démontrée dans le code suivant :
<code class="go">// 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) }</code>
En implémentant notre propre type, nous pouvons personnaliser le processus de désorganisation et éviter le besoin de réflexion, aboutissant à une solution plus propre et plus efficace.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!