比如如下 json,怎么写 struct
{
"elements": [
{ "type":abc, "这个字段只在 type=abc 时出现":value},
{ "type":def, "这个字段只在 type=def 时出现":value},
{ "abc":"xx" ,"这个字段只在 abc=xx 时出现":"value"}
]
}
1
NessajCN 2023-07-03 11:02:25 +08:00
`json:"字段,omitempty"`
|
2
seers 2023-07-03 11:07:27 +08:00 via Android
放到 interface
|
3
xdeng 2023-07-03 11:08:19 +08:00
万能的 map[string]any
|
4
jackbrother 2023-07-03 11:11:40 +08:00
后端设计不合理
|
5
mineralsalt 2023-07-03 11:14:03 +08:00
不要映射实体了,这种情况, 还不如直接用 JsonObject 取值来的方便
|
6
bv 2023-07-03 11:14:50 +08:00
@jackbrother 确实,这个 JSON 一点也不结构化,尤其是多出来的 `"abc":"xx"` 这一项显得数据关系更加松散。
|
7
Seanfuck 2023-07-03 11:17:49 +08:00
直接结构体字段写全去解析,没有的字段好像会给个默认值吧?
|
8
yuan1028 2023-07-03 11:19:04 +08:00 1
struct 为了可读性,最好是把字段都写出来;
牺牲可读性,为了代码的优雅的话,可以用字符串 json 处理库 https://github.com/tidwall/gjson ,这样不用解析。 if-else 多,只能用设计模式优化。 不过,在细微逻辑处,go 还是直来直去更合适,除非业务逻辑也比较明晰。 |
9
exkernel 2023-07-03 11:24:05 +08:00
gjson +1
|
10
HelloAmadeus 2023-07-03 11:31:07 +08:00 1
就是 oneof 的语法,oneof 也可以理解为 optional ,设计上无外乎两种方式,一种加 type 表示类型,和你这个例子类似,另外一种就是不加 type ,按优先级取值,按你这个例子就是设计上如果存在 "这个字段只在 type=abc 时出现" 对应的值,就不会取 "这个字段只在 type=def 时出现" 这个值了。
这两种方式,无论怎么样,struct 都要把所有可能的结构都写上,都得写成 ``` type Element struct { Type string `json:"type"` TypeABCValue *struct { } `json:"这个字段只在 type=abc 时出现"` TypeDEFValue *struct { } `json:"这个字段只在 type=def 时出现"` ABC string `json:"type"` ABCXXValue struct { } `json:"这个字段只在 abc=xx 时出现"` ``` |
11
ziyeziye 2023-07-03 11:37:18 +08:00
gjson +1
|
12
wangritian 2023-07-03 11:45:06 +08:00
这种 key 都不同的还好处理,全声明就完了,赞同 10 楼
|
13
gam2046 2023-07-03 12:29:12 +08:00 1
|
14
wheeler 2023-07-03 12:38:42 +08:00 via iPhone 1
rawMessage 根据 type 二次 unmarshal
|
15
Trim21 2023-07-03 12:41:45 +08:00 via Android
如果可能的 key 只有你提到的这 4 5 种的话,像 10 楼那样写个 struct 把所有可能的 key 都写上就好了…
|
17
Aumujun 2023-07-03 13:17:36 +08:00
gjson ? 取的时候判断一下
|
18
ccde8259 2023-07-03 13:21:50 +08:00 via iPhone
有的 json 包 unmarshal 出来的是 ast.Node
|
19
otakustay 2023-07-03 13:32:59 +08:00
@jackbrother 也不能说不合理吧,从类型角度考虑这就是个 union type ,要说语言的类型能力不足也行
|
20
a2231243 2023-07-03 13:53:18 +08:00
structpb.Struct 这个挺好用
|
21
janus77 2023-07-03 13:56:20 +08:00
这种内容,一般上游是 php ,要么就是这个项目的老架构是用 php 后面改 go 重写的
|
22
mxT52CRuqR6o5 2023-07-03 13:57:52 +08:00
abc 这个 key 是动态的?
|
23
dzdh OP @mxT52CRuqR6o5 其他也是动态的。后端是 php 类似 class TypeA impl jsonserialize { tojson: return [type:...
|
24
Justin13 2023-07-03 16:54:21 +08:00 via Android
上 jsonschema
|
25
lisxour 2023-07-03 16:58:42 +08:00
这种就不应该上结构体了,用 gjson 之类的去取
|
26
CloveAndCurrant 2023-07-03 17:01:52 +08:00
推荐 fastjson: github.com/valyala/fastjson
和 fasthttp 一个作者开发的 |
27
shawn4me 2023-07-03 17:06:57 +08:00
我之前做需求开发的时候也遇到这种动态字段的问题。我通常的做法是:类型作为一个字段,跟着类型变动的其他字段使用 json 字段统一存在一个字段里面。形成一个两级关系,这样就可以放心根据 type 字段进行取用了。Go 用内嵌应该也能做到,再加一个 omitempty 就能避免无用字段出现了。
|
28
bunny189 2023-07-03 19:27:40 +08:00
我个人评价为你们后端有病
|
29
lisongeee 2023-07-03 19:55:25 +08:00
如果是 typescript/scala 的话,就是一个很简单的 联合类型
|
30
sadfQED2 2023-07-03 20:18:13 +08:00 via Android
直接上正则吧,别解析了
|
31
huzhizhao 2023-07-03 23:56:09 +08:00 via iPhone 1
不知道什么类型的业务会不抽象🤔
|
32
alexapollo 2023-07-04 00:20:38 +08:00
条件结构的需求非常常见。比如不同返回码对应了不同的输出 —— 在上古 C 语言时期就已经有大量对应设计。
如: http://c.biancheng.net/view/2035.html 中有 C 语言的 union 例子 在 Python 中,你可以使用支持 Union 类型的库来实现这个功能,比如 pydantic: https://docs.pydantic.dev/latest/usage/types/unions/ 在其他语言中,你也应该搜索:<lang> json union ,来找到一个恰当的实现 |
33
Leviathann 2023-07-04 00:27:47 +08:00
数组里后面的元素依赖前面的元素的 type 字段?
什么勾把接口 |
35
rs9G7IrdOdiNR3h1 2023-07-04 09:57:02 +08:00
使用 com.google.gson.JsonDeserializer
|
36
troywinter 2023-07-04 17:16:38 +08:00
明显结构设计不合理
|
38
awanganddong 2023-07-13 14:11:57 +08:00
|