被 go 语言的 json.Marshal 恶心到了

2024-07-17 10:49:45 +08:00
 qW7bo2FbzbC0

我的需求是,输入 sql ,返回序列化后的 json 结果。

在 python 中,官方库就可以返回[{'col1': 1, 'col2': '2', 'col3': true}....] 这种带类型的 json 结果。

在 go 中如果已知 sql 返回的列数和列类型,也可以构造一个 struct 进行数据映射,然后用json.Marshal转为 json 。

如果 sql 返回的列数和行类型未知,就很难受了,在 go/mysql 的官方 wiki 案例 中对于匿名的结果,使用了 interface 或者 sql.RawBytes ,但这两种替代方式在json.Marshal后都变成了 base64 encode 后的 string ,既丢失了类型也变异了结果( https://stackoverflow.com/questions/32501784/the-sqlx-library-gives-weird-base64-encoded-looking-results)

请问各位在实际业务中遇到这个问题是怎么处理的?

在其他语言中很自然的 object 序列化为原类型,在 go 的 json.Marshal 中怎么就全变成 string 了

15971 次点击
所在节点    Go 编程语言
131 条回复
yrzs
2024-07-17 11:01:12 +08:00
FrankFang128
2024-07-17 11:05:15 +08:00
没遇到过,没看懂
3img
2024-07-17 11:08:42 +08:00
如果是不知道指针的类型,可以用反射啊
dzdh
2024-07-17 11:08:53 +08:00
我翻译一下。

up 想要 go 实现 php 的 json_encode(PDO->fethcAll()) 不定义 struct
NessajCN
2024-07-17 11:10:05 +08:00
首先 Marshal 是序列化,Unmarshal 是反序列化, 也就是从 byte 到 go struct 应该用 Unmarshal
其次,对于未知的返回类型一般不 Unmarshal , 直接从 interface 里取键值,go 自带返回 ok 判断是否有这个 key
譬如
```go
type SqlResult map[string]interface{}
var res SqlResult
if col1,ok := res["col1"].(int32); ok {
//...
}
```
povsister
2024-07-17 11:11:07 +08:00
你适合用 python
sagaxu
2024-07-17 11:13:13 +08:00
根据 ColumnType 判断一下字段类型,自己写个转换,把[]byte 和[]uint8 都转成 string
laikick
2024-07-17 11:13:15 +08:00
你适合用 PHP
zxdstyle
2024-07-17 11:14:00 +08:00
这不是 go 和 python 的区别,是强类型语言与弱类型语言的区别
Goooooos
2024-07-17 11:15:45 +08:00
@zxdstyle 其实 python 也是强类型语言
sagaxu
2024-07-17 11:19:44 +08:00
@laikick 除了 PHP ,Python 和 Java 也行,这件事情上,唯独 Go 比较大道至简
james122333
2024-07-17 11:23:25 +08:00
你可以用 map[string]any 或 json.RawMessage
james122333
2024-07-17 11:25:32 +08:00
map[string]any, []any...族繁不及备载
Nazz
2024-07-17 11:26:41 +08:00
要修改下结构体定义, 例如把 []uint8 换成 []uint16
james122333
2024-07-17 11:28:47 +08:00
看 col 举例应该是[]map[string]any
ChrisFreeMan
2024-07-17 11:29:54 +08:00
OP 赶紧跑吧你完了
luhengyuorang
2024-07-17 11:32:34 +08:00
最开始用 py 或者 php 的来写 go ,很容易有代入感,经常看到别人把 go 写成 php
dcalsky
2024-07-17 11:33:20 +08:00
收收 python 、js 、php 味。go 的正规业务里,都要得先定义 struct ,不到万不得已不用 map[string]any
liaohongxing
2024-07-17 11:33:47 +08:00
总结不适应强类型
rekulas
2024-07-17 11:36:31 +08:00
go 真冤 完全没看懂这跟 go 有什么关系

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1057942

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX