php editor Baicao today introduces to you a powerful Golang feature - Unmarshal with different structural tag sets. In Golang programming, Unmarshal is a process of converting data into a structure. However, when our data source contains different sets of structural tags, the traditional Unmarshal method may not meet the needs. Therefore, we need to use Golang Unmarshal with a different set of structural tags to achieve this functionality. This article will introduce in detail the usage and precautions of this feature. Let’s explore together!
I am using a third party tool's api which has custom key names in its json. I also have to use the api on two different environments (production and staging). Unfortunately, the custom fields in the api have different key names in both environments to represent the same data. In the example below, the json keycustom-1
in the production environment is exactly the same as the json keycustom-7
in the staging environment. I want to unmarshal any of them into the same data structure but I don't know how. I was hoping there was a way to somehow override thejson.unmarshal()
function for tags that usejson
on prod, but usejsonstaging# when staging ##. To me, this makes the most sense and is the simplest solution. I guess I'll have to write a custom
unmarshaljson(data []byte) errorfunction for my
jsonobjtype, but again, I don't know how to achieve what I want in a custom function the behavior of. Can anyone point me in the right direction, some documentation, or some examples I can use?
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) }
production: { id: "object-a", desc: "test" } staging: { id: "", desc: "" }
Production: { Id: "object-a", Desc: "test" } Staging: { Id: "object-a", Desc: "test" }
reflectpackage.
map[string] interface{}instead of the object you want to build.
objmap[tag].(
. After setting all the fields with labels it will return the new object.
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 }
The above is the detailed content of Golang Unmarshal with different set of structural tags. For more information, please follow other related articles on the PHP Chinese website!