解决前端获取后端传输的整形数据爆精度问题

本文讲述了在前端和后端数据交互中,由于数字类型范围差异可能导致数据失真的问题,提出通过将大数值转换为字符串进行序列化和反序列化来解决。作者使用Go语言的json包,展示了如何在Card结构体中使用stringtag来确保ID和Score字段在序列化和反序列化过程中的正确转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

应用背景:

前端的数字类型最大范围 为 2^-53 ~2^-53-1 ,后端int64 为 2^-63~ 2^63-1

如果后端传给前端的数据超过前端的取值返回那么这个数据便会失真,

所以后端可以先把这个数字转化为字符串再传给前端,当从前端接收到数据后再反序列化为数字

实例应用:有一个card结构体,有ID 和 Score属性这两个属性取值范围为2^-63~ 2^63-1,  实现在进行前后端数据交互时保证card里的ID和Score数据不失真。

实现json序列化(字符串与整形的序列化) 

      创建Card结构体

type Card struct {
   ID    int64   `json:"id,string"`    // 添加string tag
   Score float64 `json:"score,string"` // 添加string tag
}

创建结构体时需要在结构体成员属性后面加上tag(标签) 如 `json:"id,string"`  表示为json类型的tag tag名为id ,如果序列化将ID转化为 id 类型为string类型

go语言库封装的序列化函数

func Marshal(v any) ([]byte, error) {
   e := newEncodeState()

   err := e.marshal(v, encOpts{escapeHTML: true})
   if err != nil {
      return nil, err
   }
   buf := append([]byte(nil), e.Bytes()...)

   encodeStatePool.Put(e)

   return buf, nil
}

我们调用时只需要

package main

import (
   "encoding/json"
   "fmt"
)


type Card struct {
   ID    int64   `json:"id,string"`    // 添加string tag
   Score float64 `json:"score,string"` // 添加string tag
}

func main() {
   code := Card{1, 12.0}
   marshal, _ := json.Marshal(code)
    fmt.Println(string(marshal))//{"id":"1","score":"12"} 序列化时,key变tag值   int64 float64被序列化为string

   jsonStr1 := `{"id":"1234456","score":"88.50"}`

   var c1 Card
   if err := json.Unmarshal([]byte(jsonStr1), &c1); err != nil {
      fmt.Printf("json.Unmarsha jsonStr1 failed, err:%v\n", err)
      return
   }
   fmt.Printf("c1:%#v\n", c1) // c1:main.Card{ID:1234567, Score:88.5}
//反序列化时key为字段值   string被反序列化为 int64 float64
   fmt.Printf("c1.ID:%T\n", c1.ID)
} //#可以输出c1


    总结

   本例将 code{1,12.0} 序列化为josn格式 {"id":"1","score":"12"}
                      `{"id":"1234456","score":"88.50"}`反序列化为Card{ID:1234567, Score:88.5}
    序列化时将结构体变量名转化为tag名 类型转化为tag的类型
    反序列化时将tag名转化为结构体变量名 类型转化为结构体变量的类型
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值