比如如下 json,怎么写 struct
{ "elements": [ { "type":abc, "这个字段只在 type=abc 时出现":value}, { "type":def, "这个字段只在 type=def 时出现":value}, { "abc":"xx" ,"这个字段只在 abc=xx 时出现":"value"} ] } 
比如如下 json,怎么写 struct
{ "elements": [ { "type":abc, "这个字段只在 type=abc 时出现":value}, { "type":def, "这个字段只在 type=def 时出现":value}, { "abc":"xx" ,"这个字段只在 abc=xx 时出现":"value"} ] } 1 NessajCN Jul 3, 2023 `json:"字段,omitempty"` |
2 seers Jul 3, 2023 via Android 放到 interface |
3 46fo Jul 3, 2023 万能的 map[string]any |
4 jackbrother Jul 3, 2023 后端设计不合理 |
5 mineralsalt Jul 3, 2023 不要映射实体了,这种情况, 还不如直接用 JsonObject 取值来的方便 |
6 bv Jul 3, 2023 @jackbrother 确实,这个 JSON 一点也不结构化,尤其是多出来的 `"abc":"xx"` 这一项显得数据关系更加松散。 |
7 Seanfuck Jul 3, 2023 直接结构体字段写全去解析,没有的字段好像会给个默认值吧? |
8 yuan1028 Jul 3, 2023 struct 为了可读性,最好是把字段都写出来; 牺牲可读性,为了代码的优雅的话,可以用字符串 json 处理库 https://github.com/tidwall/gjson ,这样不用解析。 if-else 多,能用设计模式优化。 不过,在细微逻辑处,go 还是直来直去更合适,除非业务逻辑也比较明晰。 |
9 exkernel Jul 3, 2023 gjson +1 |
10 HelloAmadeus Jul 3, 2023 就是 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 Jul 3, 2023 gjson +1 |
12 wangritian Jul 3, 2023 这种 key 都不同的还好处理,全声明就完了,赞同 10 楼 |
13 ntdll Jul 3, 2023 |
14 wheeler Jul 3, 2023 via iPhone rawMessage 根据 type 二次 unmarshal |
15 Trim21 Jul 3, 2023 vi Android 如果可能的 key 只有你提到的这 4 5 种的话,像 10 楼那样写个 struct 把所有可能的 key 都写上就好了… |
17 byte404 Jul 3, 2023 gjson ? 取的时候判断一下 |
18 ccde8259 Jul 3, 2023 via iPhone 有的 json 包 unmarshal 出来的是 ast.Node |
19 otakustay Jul 3, 2023 @jackbrother 也不能说不合理吧,从类型角度考虑这就是个 union type ,要说语言的类型能力不足也行 |
20 a2231243 Jul 3, 2023 structpb.Struct 这个挺好用 |
21 rb6221 Jul 3, 2023 这种内容,一般上游是 php ,要么就是这个项目的老架构是用 php 后面改 go 重写的 |
22 mxT52CRuqR6o5 Jul 3, 2023 abc 这个 key 是动态的? |
23 dzdh OP @mxT52CRuqR6o5 其他也是动态的。后端是 php 类似 class TypeA impl jsonserialize { tojson: return [type:... |
24 Justin13 Jul 3, 2023 via Android 上 jsonschema |
25 lisxour Jul 3, 2023 这种就不应该上结构体了,用 gjson 之类的去取 |
26 CloveAndCurrant Jul 3, 2023 推荐 fastjson: github.com/valyala/fastjson 和 fasthttp 一个作者开发的 |
27 shawn4me Jul 3, 2023 我之前做需求开发的时候也遇到这种动态字段的问题。我通常的做法是:类型作为一个字段,跟着类型变动的其他字段使用 json 字段统一存在一个字段里面。形成一个两级关系,这样就可以放心根据 type 字段进行取用了。Go 用内嵌应该也能做到,再加一个 omitempty 就能避免无用字段出现了。 |
28 bunny189 Jul 3, 2023 我个人评价为你们后端有病 |
29 lisongeee Jul 3, 2023 如果是 typescript/scala 的话,就是一个很简单的 联合类型 |
30 sadfQED2 Jul 3, 2023 via Android 直接上正则吧,别解析了 |
31 huzhizhao Jul 3, 2023 via iPhone 不知道什么类型的业务会不抽象 |
32 alexapollo Jul 4, 2023 条件结构的需求非常常见。比如不同返回码对应了不同的输出 在上古 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 Jul 4, 2023 数组里后面的元素依赖前面的元素的 type 字段? 什么勾把接口 |
35 rs9G7IrdOdiNR3h1 Jul 4, 2023 使用 com.google.gson.JsonDeserializer |
36 troywinter Jul 4, 2023 明显结构设计不合理 |
38 awanganddong Jul 13, 2023 |