zoukankan      html  css  js  c++  java
  • 不要将带有 int64 的数据反序列化到 map[string]interface{} 中

    我们知道,在 Go 语言中,有一种 map 数据类型,当我们需要向哈希表中存入不确定类型的数据时,我们可能会用到 map[string]interface{}

    m1 := make(map[string]interface{}, 0)
    m1["name"] = "user1"
    m1["age"] = 21
    m1["weight"] = 130.5
    

    当向其中存储一些数据后,当我们遍历它,就能拿到自己想要的结果:

    for k, v := range m1 {
    	fmt.Printf("%s-%s
    ", k, v)
    }
    

    我们再看复杂一点的示例,服务 a,调用服务 b,获取用户信息。

    服务 b 返回 json 给服务 a:{"name": "user1","userId":3,"orgId":202505060582035456}

    // 服务 a 得到用户信息
    // 经过服务内部的接口通讯,会对数据 json 序列化和反序列化:
    json1 := `{"name": "user1","userId":3,"orgId":202505060582035456}`
    m1 := make(map[string]interface{}, 0)
    json.FromJson(json1, &m1)
    for k, v := range m1 {
    	fmt.Printf("%s-%s
    ", k, v)
    }
    t.Log(json.ToJsonIgnoreError(m1))
    

    使用 map[string]interface{} 数据接受 json 数据,会使得数值类型的数据被默认为 float64 类型。

    在上面的遍历过程中,我们可能会发现,在 for 语句体中,orgId 对应的值被默认为 float64 类型,这是 go 语言内部的机制,先不予讨论。

    这里要说的是在这种情况下,会出问题,因为 float64 不能存放 int64 的最大值,到了一定的情况下,会损失精度。上述示例中,便利得到的 orgId 值为 202505060582035460,和原始的 202505060582035456 不一致,此时就会导致比较严重的问题,比如查询用户企业查询不到等。

    要解决这个问题,办法有多种,比如我们可以让,数据反序列化到结构体中:

    type User struct {
    	Name     string `json:"name"`
    	UserId   int64  `json:"userId"`
    	OrgId    int64  `json:"orgId"`
    }
    user := User{}
    json.FromJson(json1, &user)
    
    持之以恒!
  • 相关阅读:
    C 语言编程 — 基本语法
    C 语言编程 — 函数
    C 语言编程 — 逻辑控制语句
    C 语言编程 — 运算符
    C 语言编程 — 变量与常量
    C 语言编程 — 基本数据类型
    程序编译流程与 GCC 编译器
    OpenNESS NTS 的前世今生
    通过 OpenAPI 部署 Nbsf_Management API Service
    PCF 的 Npcf_PolicyAuthorization 服务化接口
  • 原文地址:https://www.cnblogs.com/ishenghuo/p/14490278.html
Copyright © 2011-2022 走看看