最近学习开发小程序(应付课程),在和后端联调中遇到一个感觉挺离谱但又常见的问题,记录一下

💥 问题描述

项目中使用 雪花算法 生成的 ID

正常从后端返回给前端,结果到了前端居然 ID 发生变化 ?

📷 具体情况–两端对比

后端传值

前端接收

1
2

93316228403171328 -> 93316228403171330

开发经验还是太少了,以为是“屎山”导致的,研究了半个多小时决定后台新建用户测试数据

直到后来又遇到,这才了解到原因

1
1751567112993759732 -> 1751567112993759700

🧠 原因分析

后端我们用的是 Golang,ID 类型是 int64 (如果Java是 long

int64 64 位整数,范围为:

1
-9223372036854775808 到 9223372036854775807 ( -2^63 ~ 2^63 - 1 )

前端的 JavaScript 中 Number 类型使用的是 IEEE 754 双精度浮点数(64 位)

但只有 53 位是用于存储有效数字的二进制精度

1
9007199254740991 ( -2^53 ~ 2^53 - 1 )

所以导致精度丢失……

第一次:超出 2^53,低位被四舍五入

第二次:超出精度范围,低位截断为整百

✅ 解决方案

解决方式其实很简单:不要直接传 Long 类型到前端,而是序列化为字符串

将 ID 序列化成 String 传输处理:

1
2
3
4
5
type Int64String int64

func (i Int64String) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%d"`, i)), nil
}

这样一来,前端接收到的就是字符串类型就不会丢失精度

🗣️ 其他

uniapp开发微信小程序体验:

  • 不能用Linux(NO Wine!)
  • 组件库看广告(uview-plus)
  • 快速上线(5天就糊完了hh)