我要 json 序列化一个外部类型的变量,把所有 int 类型变量都序列化成"010101"
这种表示。
类似 Java 里的 Gson ,想把自定义的 int 序列化逻辑注册进去。
这要怎么做到?
举个例子。下面的类型都是所引用的库里吗的
type Person struct { name string age int home Home } type Home struct { number int district string }
现在有一个变量
var p Person
我怎么用一种比较优雅的方式来序列化p
,把它里面所有的int都序列化成"010101"
这种表示?
![]() | 1 dreasky 2022-06-17 15:00:14 +08:00 |
2 14v45mJPBYJW8dT7 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) } |
3 14v45mJPBYJW8dT7 2022-06-17 15:08:26 +08:00 #2 代码有点问题,但流程是对的 return big.NewInt(int64(int(v) + 1)).Bytes(), nil |
![]() | 4 x97bgt OP @dreasky @rimutuyuan 外部类型里的变量是 int ,不是自定义类型。 这样的话,我还需要对这个外部变量再创建一个自定义类型,然后把 int 字段替换成 MyInt 。 如果这个外部变量里面又嵌套了其他外部类型,那我都要对他们每个都创建一个自定义类型。这样写太反人类了。。。 |
5 14v45mJPBYJW8dT7 2022-06-17 15:14:29 +08:00 |
![]() | 6 x97bgt OP |
7 14v45mJPBYJW8dT7 2022-06-17 15:32:50 +08:00 |
![]() | 8 x97bgt OP |
![]() | 9 cloverstd 2022-06-17 15:50:20 +08:00 |
10 14v45mJPBYJW8dT7 2022-06-17 15:50:21 +08:00 @x97bgt 那就不能了 |
11 icexin 2022-06-17 17:16:38 +08:00 |
![]() | 12 Egfly 2022-06-17 17:32:22 +08:00 土办法,引用第三方库的 struct ,你改变不了。那就在你的代码定义一个相同字段的 struct ,然后实现 MarshalJSON()方法 多了一步遍历转换的过程,看 OP 能不能接受 |
![]() | 13 join 2022-06-17 17:35:21 +08:00 随便找段 json 复制进去就能生成对应的 struct 类型了,这个工具我写 go 时经常用。 https://mholt.github.io/json-to-go/ |
![]() | 14 zoharSoul 2022-06-17 17:36:09 +08:00 ![]() 在 golang 里面应该不行, 大道至简, 别琢磨巧妙的方法了. 大道至简的要义就是, 嗦就嗦, 多点代码也没啥, 省脑子. |
15 icexin 2022-06-17 18:24:15 +08:00 ![]() |
![]() | 16 Kisesy 2022-06-17 18:44:38 +08:00 可以用 github.com/json-iterator/go 的扩展功能给 int 类型注册一个自定义编码 |
![]() | 17 hxtheone 2022-06-17 19:54:03 +08:00 via iPhone 原生做法感觉只能定义一个一样的 struct 然后自定义字段序列化方式,加一步数据的转换 |
![]() | 18 wheeler 2022-06-17 21:26:37 +08:00 via iPhone go 里方法定义得和类型定义在一个包里,这样应该搞不定。 |
![]() | 20 x97bgt OP |
22 joesonw 2022-06-18 00:20:43 +08:00 via iPhone 你想要的是类似 swift 的 extension ,任意地方可以扩展一个类的方法。这样的坏处是 implicitity ,你用了一堆库,某个库把另一个库的 MashalJSON 给改了,你得到的结果就是一头雾水,明明自己没改呀。 |
![]() | 23 x97bgt OP @joesonw 这个看设计,因为 go 里面的序列化器都是全局的,所以改一个地方就会影响好多个地方。 像 java 的 Gson 就不会,用的时候新建一个 instance 然后注册进逻辑就可以,只有使用它的地方才带这个逻辑。 |
![]() | 24 lysS 2022-06-19 15:06:09 +08:00 你说的自定义 json 序列化方式是加 tag 吗? 你可以自定义一个自己的完全一样的 struct type MyPerson struct { name string `我的自定义 tag` age int home Home } 然后把 p 强制类型转换后再序列化 json.Marshal(MyPerson(p)) |
![]() | 25 x97bgt OP @lysS 不是。我说的是把'{"name": "Alice", "age": 10, "home": {"district": "XX", "number": 1}}',变成'{"name": "Alice", "age": "1010", "home": {"district": "XX", "number": "01"}}'这样,就是把里面所有的 int 数值类型全部换一个序列化方式。 是需要引入中间变量 |