在使用
grpc
的时候,proto
的类型定义成int64
,但结果展示却显示成string
类型。刚开始还纳闷客户端说文档上定义int类型,为啥不和文档统一呢? 自信的我坚定的回答我定义的就是int类型的,统一的很。然后模拟完接口请求,打脸来得真快。
问题复现
- 定义
proto
文件
|
|
- 返回值:
|
|
我们看到返回值中createdAt与lastTime已经变成是string类型的。
究其原因
翻阅proto的文档,可以看到,其实官方已经定义了某些类型及对应的返回值。明确的定义了int64
类型的返回值是string
.
但官方为什么这么做。其实是和javascript
中number
的实现有关,javascript
中的number
的最大精度是2的52次方,如果超过该数,
就会缺少精度。因此,grpc
的处理方式是将int64
处理成string
类型。
github
上相关issue
的一个解释:
https://github.com/protocolbuffers/protobuf/issues/8331
这是另一个解释,本质上是和上面的一样的,因为中间会将proto
文件转换成json
,而json
是基于javascript
的标准的。因此,int64
是不属于这个标准的,在这个标准体系里,int64
会丢失精度。
https://github.com/golang/protobuf/issues/1280
解决方案
个人感觉只要使用json
作为通信协议就无解,使用其他方式的通信协议就可以规避。但目前来说,json
的通信协议还是最普遍的,因此也只能这样。
当然这个json
不作为前后商通信,只是在同个项目里流转,比如golang
,就可以使用json.NewEncoder
相关的方式去处理。
参考文献
https://developers.google.com/protocol-buffers/docs/proto3#json
https://github.com/protocolbuffers/protobuf/issues/8520
https://github.com/protocolbuffers/protobuf/issues/8331
https://github.com/golang/protobuf/issues/1280
https://www.jianshu.com/p/12b734ecd08b