不懂就问: go 里面如何自定义外部类型的 json 序列化方式?

2022-06-17 14:52:32 +08:00
 x97bgt

我要 json 序列化一个外部类型的变量,把所有 int 类型变量都序列化成"010101"这种表示。

类似 Java 里的 Gson ,想把自定义的 int 序列化逻辑注册进去。

这要怎么做到?

2497 次点击
所在节点    Go 编程语言
25 条回复
dreasky
2022-06-17 15:00:14 +08:00
rimutuyuan
2022-06-17 15:04:10 +08:00
自定义类型,实现 MarshalJSON 方法

type MyInt int

func (v MyInt) MarshalJSON() ([]byte, error) {

return big.NewInt(int64(int(v) + 1)).Bytes(), nil
}

func main() {
m := MyInt(1)
json.Marshal(m)
}
rimutuyuan
2022-06-17 15:08:26 +08:00
#2 代码有点问题,但流程是对的

return big.NewInt(int64(int(v) + 1)).Bytes(), nil
x97bgt
2022-06-17 15:10:37 +08:00
@dreasky
@rimutuyuan

外部类型里的变量是 int ,不是自定义类型。

这样的话,我还需要对这个外部变量再创建一个自定义类型,然后把 int 字段替换成 MyInt 。

如果这个外部变量里面又嵌套了其他外部类型,那我都要对他们每个都创建一个自定义类型。这样写太反人类了。。。
rimutuyuan
2022-06-17 15:14:29 +08:00
@x97bgt 只修改最外层即可

如 type Person struct {name string, age int},只需要实现 Person 的 MarshalJSON ,然后拼接
x97bgt
2022-06-17 15:19:41 +08:00
@rimutuyuan

有点不大明白。这个 Person 是外部类型,我怎么能实现它的 MarshalJSON ?
rimutuyuan
2022-06-17 15:32:50 +08:00
@x97bgt

func (p *Person) MarshalJSON() ([]byte, error) {}
x97bgt
2022-06-17 15:36:24 +08:00
@rimutuyuan

还是有点搞不明白。

这个 Person 是我所引用的库里的类型。可以给这种外部类型实现新的方法?
cloverstd
2022-06-17 15:50:20 +08:00
rimutuyuan
2022-06-17 15:50:21 +08:00
@x97bgt 那就不能了
icexin
2022-06-17 17:16:38 +08:00
Egfly
2022-06-17 17:32:22 +08:00
土办法,引用第三方库的 struct ,你改变不了。那就在你的代码定义一个相同字段的 struct ,然后实现 MarshalJSON()方法

多了一步遍历转换的过程,看 OP 能不能接受
join
2022-06-17 17:35:21 +08:00
随便找段 json 复制进去就能生成对应的 struct 类型了,这个工具我写 go 时经常用。
https://mholt.github.io/json-to-go/
zoharSoul
2022-06-17 17:36:09 +08:00
在 golang 里面应该不行, 大道至简, 别琢磨巧妙的方法了.

大道至简的要义就是, 啰嗦就啰嗦, 多点代码也没啥, 省脑子.
icexin
2022-06-17 18:24:15 +08:00
Kisesy
2022-06-17 18:44:38 +08:00
可以用 github.com/json-iterator/go 的扩展功能给 int 类型注册一个自定义编码
hxtheone
2022-06-17 19:54:03 +08:00
原生做法感觉只能定义一个一样的 struct 然后自定义字段序列化方式,加一步数据的转换
wheeler
2022-06-17 21:26:37 +08:00
go 里方法定义得和类型定义在一个包里,这样应该搞不定。
x97bgt
2022-06-17 21:28:48 +08:00
@cloverstd
@Kisesy

这个库貌似可以实现,但实在有点抗拒为了这功能又引入一个新东西。。。多谢老歌
x97bgt
2022-06-17 21:34:16 +08:00
@Egfly
@icexin
@hxtheone
@wheeler

这也是我想到的:先写一些数据作为中间层,把全部的外部类型都继承一遍。。。。

没想到只能这么写。。。对 go 这语言改观了。。

多谢大家

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

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

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

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

© 2021 V2EX