Golang Go语言中怎么优雅的处理不固定的 json 内容
比如如下 json,怎么写 struct
{
"elements": [
{ "type":abc, "这个字段只在 type=abc 时出现":value},
{ "type":def, "这个字段只在 type=def 时出现":value},
{ "abc":"xx" ,"这个字段只在 abc=xx 时出现":"value"}
]
}
Golang Go语言中怎么优雅的处理不固定的 json 内容
更多关于Golang Go语言中怎么优雅的处理不固定的 json 内容的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
json:"字段,omitempty"
更多关于Golang Go语言中怎么优雅的处理不固定的 json 内容的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
放到 interface
万能的 map[string]any
后端设计不合理
不要映射实体了,这种情况, 还不如直接用 JsonObject 取值来的方便
确实,这个 JSON 一点也不结构化,尤其是多出来的 "abc":"xx"
这一项显得数据关系更加松散。
直接结构体字段写全去解析,没有的字段好像会给个默认值吧?
struct 为了可读性,最好是把字段都写出来;
牺牲可读性,为了代码的优雅的话,可以用字符串 json 处理库 https://github.com/tidwall/gjson ,这样不用解析。
if-else 多,只能用设计模式优化。
不过,在细微逻辑处,go 还是直来直去更合适,除非业务逻辑也比较明晰。
就是 oneof 的语法,oneof 也可以理解为 optional ,设计上无外乎两种方式,一种加 type 表示类型,和你这个例子类似,另外一种就是不加 type ,按优先级取值,按你这个例子就是设计上如果存在 “这个字段只在 type=abc 时出现” 对应的值,就不会取 “这个字段只在 type=def 时出现” 这个值了。
这两种方式,无论怎么样,struct 都要把所有可能的结构都写上,都得写成<br>type Element struct {<br> Type string `json:"type"`<br> TypeABCValue *struct {<br> } `json:"这个字段只在 type=abc 时出现"`<br> TypeDEFValue *struct {<br> } `json:"这个字段只在 type=def 时出现"`<br> <br> ABC string `json:"type"`<br> ABCXXValue struct {<br> } `json:"这个字段只在 abc=xx 时出现"`<br>
gjson +1
这种 key 都不同的还好处理,全声明就完了,赞同 10 楼
rawMessage 根据 type 二次 unmarshal
如果可能的 key 只有你提到的这 4 5 种的话,像 10 楼那样写个 struct 把所有可能的 key 都写上就好了…
审题朋友,rawMessage 只适合 key 相同的情况,楼主这是 key 都不同
gjson ? 取的时候判断一下
有的 json 包 unmarshal 出来的是 ast.Node
也不能说不合理吧,从类型角度考虑这就是个 union type ,要说语言的类型能力不足也行
structpb.Struct 这个挺好用
这种内容,一般上游是 php ,要么就是这个项目的老架构是用 php 后面改 go 重写的
abc 这个 key 是动态的?
其他也是动态的。后端是 php 类似 class TypeA impl jsonserialize { tojson: return [type:…
上 jsonschema
这种就不应该上结构体了,用 gjson 之类的去取
推荐 fastjson: github.com/valyala/fastjson
和 fasthttp 一个作者开发的
我之前做需求开发的时候也遇到这种动态字段的问题。我通常的做法是:类型作为一个字段,跟着类型变动的其他字段使用 json 字段统一存在一个字段里面。形成一个两级关系,这样就可以放心根据 type 字段进行取用了。Go 用内嵌应该也能做到,再加一个 omitempty 就能避免无用字段出现了。
我个人评价为你们后端有病
如果是 typescript/scala 的话,就是一个很简单的 联合类型
直接上正则吧,别解析了
不知道什么类型的业务会不抽象🤔
条件结构的需求非常常见。比如不同返回码对应了不同的输出 —— 在上古 C 语言时期就已经有大量对应设计。
如: http://c.biancheng.net/view/2035.html 中有 C 语言的 union 例子
在 Python 中,你可以使用支持 Union 类型的库来实现这个功能,比如 pydantic: https://docs.pydantic.dev/latest/usage/types/unions/
在其他语言中,你也应该搜索:<lang> json union ,来找到一个恰当的实现
数组里后面的元素依赖前面的元素的 type 字段?
什么勾把接口
PHP 后台能给你个 JSON 已经很不错了
使用 com.google.gson.JsonDeserializer
明显结构设计不合理
确实,深有体会
这个帖子是一个解决方案
Go 如何解析 json 内部结构不确定的情况
https://my.oschina.net/u/4628563/blog/4724059
在Golang中处理不固定的JSON内容时,优雅的做法通常涉及使用map、interface{}类型以及结构体标签(struct tags)的组合。以下是一些建议:
-
使用map[string]interface{}: 当JSON结构未知或变化时,可以将JSON解码到一个map[string]interface{}中。这允许你动态地访问JSON对象的键值对。
var data map[string]interface{} err := json.Unmarshal([]byte(jsonStr), &data) if err != nil { // 处理错误 } // 访问数据 value, ok := data["key"].(string) if ok { fmt.Println(value) }
-
定义部分结构体并使用interface{}: 如果JSON中有部分结构是已知的,可以定义一个结构体来匹配这些已知字段,并将未知字段捕获到interface{}中。
type KnownFields struct { Field1 string `json:"field1"` Rest map[string]interface{} `json:"-"` // 使用json:"-"忽略此字段的直接解析 } var kf KnownFields json.Unmarshal([]byte(jsonStr), &struct { KnownFields Rest map[string]interface{} `json:",inline"` }{ Rest: &kf.Rest, })
-
错误处理: 在处理动态JSON时,务必做好错误处理,特别是类型断言(type assertion)失败的情况。
通过上述方法,你可以灵活且优雅地处理不固定的JSON内容,同时保持代码的清晰和可维护性。