Maison >développement back-end >Golang >Golang Unmarshal avec différents ensembles de balises structurelles
L'éditeur php Baicao vous présente aujourd'hui une puissante fonctionnalité Golang - Unmarshal avec différents ensembles de balises structurelles. Dans la programmation Golang, Unmarshal est un processus de conversion de données en structure. Cependant, lorsque notre source de données contient différents ensembles de balises structurelles, la méthode traditionnelle Unmarshal peut ne pas répondre aux besoins. Par conséquent, nous devons utiliser Golang Unmarshal avec un ensemble différent de balises structurelles pour obtenir cette fonctionnalité. Cet article présentera en détail l'utilisation et les précautions de cette fonctionnalité. Explorons ensemble !
J'utilise l'API d'un outil tiers qui a des noms de clés personnalisés dans son json. Je dois également utiliser l'API sur deux environnements différents (production et staging). Malheureusement, les champs personnalisés de l'API ont des noms de clé différents dans les deux environnements pour représenter les mêmes données. Dans l'exemple ci-dessous, la clé json custom-1
与暂存环境中的 json 密钥 custom-7
完全相同。我想将其中任何一个解组到相同的数据结构中,但我不知道如何进行。我希望有一种方法可以以某种方式覆盖 json.unmarshal()
函数用于在 prod 上使用 json
的标签,但在暂存时使用 jsonstaging
。对我来说,这是最有意义且最简单的解决方案。我猜我必须为我的 jsonobj
类型编写一个自定义 unmarshaljson(data []byte) error
fonctionne en production, mais encore une fois, je ne sais pas comment obtenir le comportement souhaité dans une fonction personnalisée. Quelqu'un peut-il m'orienter dans la bonne direction, de la documentation ou des exemples que je peux utiliser ?
package main import ( "encoding/json" "fmt" ) type jsonobj struct { id string `json:"custom-1" jsonstaging:"custom-7"` desc string `json:"custom-2" jsonstaging:"custom-8"` } func (i jsonobj) string() string { return fmt.sprintf(`{ id: "%s", desc: "%s" }`, i.id, i.desc) } func main() { var jsonprod = `{ "custom-1": "object-a", "custom-2": "test" } ` var jsonstaging = `{ "custom-7": "object-a", "custom-8": "test" } ` var jsonobjprod jsonobj var jsonobjstaging jsonobj json.unmarshal([]byte(jsonprod), &jsonobjprod) json.unmarshal([]byte(jsonstaging), &jsonobjstaging) fmt.println("production: ", jsonobjprod) fmt.println("staging: ", jsonobjstaging) }
Quand je l'exécute avec go run, j'obtiens
production: { id: "object-a", desc: "test" } staging: { id: "", desc: "" }
C'est ce qu'attend mon code actuel, mais j'aimerais l'obtenir
Production: { Id: "object-a", Desc: "test" } Staging: { Id: "object-a", Desc: "test" }
Je ne peux pas modifier l'API de l'environnement de préparation ou de production.
J'ai essayé de créer différentes structures et interfaces, mais à mesure que le nombre de champs (et de clés JSON personnalisées) augmente (et ils grandissent), cela semble être un cauchemar de maintenance. S'il vous plaît, aidez-moi si c'est le seul moyen, je ne l'ai pas non plus fait fonctionner avant de décider que ce n'était peut-être pas le bon chemin.
Pour référence future, si quelqu'un veut faire cela, je pense avoir trouvé un moyen en utilisant le package reflect
intégré.
Tout d'abord, vous devez utiliser la fonction json.unmarshal(), mais remplissez map[string] 接口{}
à la place de l'objet que vous souhaitez construire.
Ensuite, j'ai écrit une fonction qui récupère l'environnement et la carte. Il parcourt tous les champs de la nouvelle instance de l'objet réel (pas la carte) et obtient l'étiquette de l'environnement que vous utilisez. Il définit ensuite les champs du nouvel objet sur objmap[tag].(f215d538f93896d2fa3ea4137b420524)
. Après avoir défini tous les champs avec des étiquettes, le nouvel objet sera renvoyé.
Voici mon code de travail :
package main import ( "encoding/json" "fmt" "reflect" ) const ( StagingStructTag = "jsonStaging" ProductionStructTag = "json" ) type jsonObj struct { Id string `json:"custom-1" jsonStaging:"custom-7"` Desc string `json:"custom-2" jsonStaging:"custom-8"` } func (i jsonObj) String() string { return fmt.Sprintf(`{ Id: "%s", Desc: "%s" }`, i.Id, i.Desc) } func main() { var jsonProd = `{ "custom-1": "object-a", "custom-2": "test" } ` var jsonStaging = `{ "custom-7": "object-a", "custom-8": "test" } ` var env string = "staging" var jsonObjProd jsonObj var jsonObjStaging jsonObj var jsonObjProdMap map[string]interface{} var jsonObjStagingMap map[string]interface{} json.Unmarshal([]byte(jsonStaging), &jsonObjStagingMap) json.Unmarshal([]byte(jsonProd), &jsonObjProdMap) jsonObjStaging = BuildJsonObj(env, jsonObjStagingMap) env = "production" jsonObjProd = BuildJsonObj(env, jsonObjProdMap) fmt.Println("Production: ", jsonObjProd) fmt.Println("Staging: ", jsonObjStaging) } func BuildJsonObj(env string, objMap map[string]interface{}) jsonObj { var obj jsonObj var t reflect.Type = reflect.TypeOf(obj) var structTagName string if env == "staging" { structTagName = StagingStructTag } else if env == "production" { structTagName = ProductionStructTag } for i := 0; i < t.NumField(); i++ { var field reflect.StructField = t.Field(i) var tag string var ok bool if tag, ok = field.Tag.Lookup(structTagName); ok { switch field.Name { case "Id": obj.Id = objMap[tag].(string) case "Desc": obj.Desc = objMap[tag].(string) } } } return obj }
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!