Heim >Backend-Entwicklung >Golang >Golang Unmarshal mit unterschiedlichen Struktur-Tags
php-Editor Baicao stellt Ihnen heute eine leistungsstarke Golang-Funktion vor – Unmarshal mit verschiedenen strukturellen Tag-Sets. In der Golang-Programmierung ist Unmarshal ein Prozess zum Konvertieren von Daten in eine Struktur. Wenn unsere Datenquelle jedoch unterschiedliche Sätze struktureller Tags enthält, erfüllt die herkömmliche Unmarshal-Methode möglicherweise nicht die Anforderungen. Daher müssen wir Golang Unmarshal mit einem anderen Satz struktureller Tags verwenden, um diese Funktionalität zu erreichen. In diesem Artikel werden die Verwendung und Vorsichtsmaßnahmen dieser Funktion ausführlich vorgestellt. Lasst uns gemeinsam erkunden!
Ich verwende die API eines Drittanbieter-Tools und deren JSON enthält benutzerdefinierte Schlüsselnamen. Ich muss die API auch in zwei verschiedenen Umgebungen verwenden (Produktion und Staging). Leider haben die benutzerdefinierten Felder in der API in beiden Umgebungen unterschiedliche Schlüsselnamen, um dieselben Daten darzustellen. Im folgenden Beispiel funktioniert der JSON-Schlüssel custom-1
与暂存环境中的 json 密钥 custom-7
完全相同。我想将其中任何一个解组到相同的数据结构中,但我不知道如何进行。我希望有一种方法可以以某种方式覆盖 json.unmarshal()
函数用于在 prod 上使用 json
的标签,但在暂存时使用 jsonstaging
。对我来说,这是最有意义且最简单的解决方案。我猜我必须为我的 jsonobj
类型编写一个自定义 unmarshaljson(data []byte) error
in der Produktion, aber auch hier weiß ich nicht, wie ich das gewünschte Verhalten in einer benutzerdefinierten Funktion erreichen kann. Kann mir jemand den richtigen Weg weisen, eine Dokumentation oder Beispiele, die ich verwenden kann?
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) }
Wenn ich es mit „Go Run“ ausführe, erhalte ich
production: { id: "object-a", desc: "test" } staging: { id: "", desc: "" }
Das ist es, was mein aktueller Code erwartet, aber ich würde gerne bekommen
Production: { Id: "object-a", Desc: "test" } Staging: { Id: "object-a", Desc: "test" }
Ich kann die API der Staging- oder Produktionsumgebung nicht ändern.
Ich habe versucht, verschiedene Strukturen und Schnittstellen zu erstellen, aber da die Anzahl der Felder (und benutzerdefinierten JSON-Schlüssel) zunimmt (und wächst), scheint es ein Wartungsalptraum zu sein. Bitte helfen Sie mir, wenn dies der einzige Weg ist. Ich habe es auch nicht zum Laufen gebracht, bevor ich entschieden habe, dass dies möglicherweise nicht der richtige Weg ist.
Falls jemand dies in Zukunft tun möchte, denke ich, dass ich einen Weg gefunden habe, das integrierte reflect
-Paket zu verwenden.
Zuerst müssen Sie die Funktion json.unmarshal() verwenden, aber map[string] 接口{}
anstelle des Objekts eingeben, das Sie erstellen möchten.
Dann habe ich eine Funktion geschrieben, die die Umgebung und die Karte abruft. Es durchläuft alle Felder in der neuen Instanz des tatsächlichen Objekts (nicht der Karte) und ruft die Bezeichnung für die von Ihnen verwendete Umgebung ab. Anschließend werden die Felder im neuen Objekt auf objmap[tag].(f215d538f93896d2fa3ea4137b420524)
gesetzt. Nachdem alle Felder mit Beschriftungen versehen wurden, wird das neue Objekt zurückgegeben.
Das ist mein Arbeitscode:
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 }
Das obige ist der detaillierte Inhalt vonGolang Unmarshal mit unterschiedlichen Struktur-Tags. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!