具有不同结构标签集的 Golang Unmarshal
php小编百草今天为大家介绍一种强大的Golang特性——具有不同结构标签集的Unmarshal。在Golang编程中,Unmarshal是一种将数据转换为结构体的过程。但是,当我们的数据源包含不同的结构标签集时,传统的Unmarshal方法可能无法满足需求。因此,我们需要使用具有不同结构标签集的Golang Unmarshal来实现这一功能。本文将详细介绍这个特性的使用方法和注意事项。让我们一起来探索吧!
问题内容
我正在使用第三方工具的 api,它的 json 中包含自定义键名称。我还必须在两个不同的环境(生产环境和登台环境)上使用 api。不幸的是,api 中的自定义字段在两个环境中具有不同的键名称来表示相同的数据。在下面的示例中,生产环境中的 json 密钥 custom-1
与暂存环境中的 json 密钥 custom-7
完全相同。我想将其中任何一个解组到相同的数据结构中,但我不知道如何进行。我希望有一种方法可以以某种方式覆盖 json.unmarshal()
函数用于在 prod 上使用 json
的标签,但在暂存时使用 jsonstaging
。对我来说,这是最有意义且最简单的解决方案。我猜我必须为我的 jsonobj
类型编写一个自定义 unmarshaljson(data []byte) error
函数,但同样,我不知道如何在自定义函数中实现所需的行为。有人能给我指出正确的方向、一些文档或一些我可以使用的示例吗?
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) }
当我用 go run 运行它时,我得到
production: { id: "object-a", desc: "test" } staging: { id: "", desc: "" }
这是我当前代码所期望的,但我想得到
Production: { Id: "object-a", Desc: "test" } Staging: { Id: "object-a", Desc: "test" }
我无法修改临时环境或生产环境的 api。
我尝试过创建不同的结构和接口,但是随着字段数量(以及自定义 json 键)的增加(它们会增加),这似乎是维护的噩梦。如果这是唯一的方法,请帮助我,在我决定这可能不是正确的路径之前,我也没有让它发挥作用。
解决方法
为了将来参考,如果有人想这样做,我想我找到了一种使用内置 reflect
包的方法。
首先,您必须使用 json.unmarshal() 函数,但填充 map[string] 接口{}
而不是您要构建的对象。
然后我编写了一个获取环境和地图的函数。它会遍历实际对象(而不是地图)的新实例中的所有字段,并获取您正在使用的环境的标签。然后它将新对象中的字段设置为 objmap[tag].(<variable_type>)
。使用标签设置所有字段后,它将返回新对象。
这是我的工作代码:
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 }
以上是具有不同结构标签集的 Golang Unmarshal的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

本文解释了GO的软件包导入机制:命名imports(例如导入“ fmt”)和空白导入(例如导入_ fmt; fmt;)。 命名导入使包装内容可访问,而空白导入仅执行t

本文详细介绍了MySQL查询结果的有效转换为GO结构切片。 它强调使用数据库/SQL的扫描方法来最佳性能,避免手动解析。 使用DB标签和Robus的结构现场映射的最佳实践

本文解释了Beego的NewFlash()函数,用于Web应用程序中的页间数据传输。 它专注于使用newflash()在控制器之间显示临时消息(成功,错误,警告),并利用会话机制。 Lima

本文演示了创建模拟和存根进行单元测试。 它强调使用接口,提供模拟实现的示例,并讨论最佳实践,例如保持模拟集中并使用断言库。 文章

本文探讨了GO的仿制药自定义类型约束。 它详细介绍了界面如何定义通用功能的最低类型要求,从而改善了类型的安全性和代码可重复使用性。 本文还讨论了局限性和最佳实践

本文详细介绍了在GO中详细介绍有效的文件,将OS.WriteFile(适用于小文件)与OS.openfile和缓冲写入(最佳大型文件)进行比较。 它强调了使用延迟并检查特定错误的可靠错误处理。

本文使用跟踪工具探讨了GO应用程序执行流。 它讨论了手册和自动仪器技术,比较诸如Jaeger,Zipkin和Opentelemetry之类的工具,并突出显示有效的数据可视化
