Rumah >pembangunan bahagian belakang >Golang >Golang Unmarshal dengan set tag struktur yang berbeza
editor php Baicao hari ini memperkenalkan anda kepada ciri Golang yang berkuasa - Unmarshal dengan set tag struktur yang berbeza. Dalam pengaturcaraan Golang, Unmarshal ialah proses menukar data kepada struktur. Walau bagaimanapun, apabila sumber data kami mengandungi set teg struktur yang berbeza, kaedah Unmarshal tradisional mungkin tidak memenuhi keperluan. Oleh itu, kita perlu menggunakan Golang Unmarshal dengan set tag struktur yang berbeza untuk mencapai fungsi ini. Artikel ini akan memperkenalkan secara terperinci penggunaan dan langkah berjaga-jaga bagi ciri ini. Mari kita meneroka bersama-sama!
Saya menggunakan api alat pihak ketiga yang mempunyai nama kunci tersuai dalam jsonnya. Saya juga perlu menggunakan api pada dua persekitaran berbeza (pengeluaran dan pementasan). Malangnya, medan tersuai dalam api mempunyai nama kunci yang berbeza dalam kedua-dua persekitaran untuk mewakili data yang sama. Dalam contoh di bawah, kunci json custom-1
与暂存环境中的 json 密钥 custom-7
完全相同。我想将其中任何一个解组到相同的数据结构中,但我不知道如何进行。我希望有一种方法可以以某种方式覆盖 json.unmarshal()
函数用于在 prod 上使用 json
的标签,但在暂存时使用 jsonstaging
。对我来说,这是最有意义且最简单的解决方案。我猜我必须为我的 jsonobj
类型编写一个自定义 unmarshaljson(data []byte) error
berfungsi dalam pengeluaran, tetapi sekali lagi, saya tidak tahu bagaimana untuk mencapai tingkah laku yang diingini dalam fungsi tersuai. Bolehkah sesiapa menunjukkan saya ke arah yang betul, beberapa dokumentasi atau beberapa contoh yang boleh saya gunakan?
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) }
Apabila saya menjalankannya dengan go run saya mendapat
production: { id: "object-a", desc: "test" } staging: { id: "", desc: "" }
Ini adalah kod semasa saya jangkakan, tetapi saya ingin mendapatkan
Production: { Id: "object-a", Desc: "test" } Staging: { Id: "object-a", Desc: "test" }
Saya tidak boleh mengubah suai api persekitaran pementasan atau pengeluaran.
Saya telah cuba mencipta struktur dan antara muka yang berbeza, tetapi apabila bilangan medan (dan kekunci json tersuai) meningkat (dan ia berkembang), ia nampaknya menjadi mimpi ngeri penyelenggaraan. Tolong bantu saya jika ini adalah satu-satunya cara, saya juga tidak berjaya melakukannya sebelum saya memutuskan ini mungkin bukan jalan yang betul. .
reflect
Kemudian saya menulis fungsi yang mendapat persekitaran dan peta. Ia menggelung melalui semua medan dalam contoh baharu objek sebenar (bukan peta) dan mendapat label untuk persekitaran yang anda gunakan. Ia kemudian menetapkan medan dalam objek baharu kepada
map[string] 接口{}
Ini kod kerja saya:
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 }
Atas ialah kandungan terperinci Golang Unmarshal dengan set tag struktur yang berbeza. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!