登录
首页 >  Golang >  Go问答

Golang中JSON编组和解组期间数字不匹配

来源:stackoverflow

时间:2024-02-25 10:00:29 426浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《Golang中JSON编组和解组期间数字不匹配》,聊聊,希望可以帮助到正在努力赚钱的你。

问题内容

package main

import (
    "encoding/json"
    "fmt"
)

func t() {
    a := int64(1<<63 - 1)
    fmt.println(a)
    m := map[string]interface{}{
        "balance": a,
    }

    data, _ := json.marshal(m)
    m1 := make(map[string]interface{})
    err := json.unmarshal(data, &m1)
    panicif(err)
    fmt.println(int64(m1["balance"].(float64)))
}

func panicif(err error) {
    if err != nil {
        panic(err)
    }
}

运行上面的代码将打印:

9223372036854775807
-9223372036854775808

您能解释一下这个问题吗?我在某处读到,在 json 中,我们不应该将数字 > 2^53 与数字类型一起使用,而应该使用字符串类型。


正确答案


当解组到 map[string]any 类型的映射时,encoding/json 包将选择 float64 类型来解组数字。

数字 9223372036854775807 无法用 float64 类型的值精确表示,因此将表示接近它的其他数字,此处即 9223372036854775808.0。当您将此数字转换为 int64 时,由于它超出了 int64 的有效范围,因此结果显然会是其他内容,在您的情况下是可表示的 int64 值的最小值。

添加一些额外的日志记录语句:

data, err := json.marshal(m)
panicif(err)
fmt.println(string(data))
m1 := make(map[string]interface{})
err = json.unmarshal(data, &m1)
panicif(err)
fmt.println(m1)
fmt.printf("%f\n", m1["balance"].(float64))
fmt.println(int64(m1["balance"].(float64)))

这将输出(在 Go Playground 上尝试):

9223372036854775807
{"balance":9223372036854775807}
map[balance:9.223372036854776e+18]
9223372036854775808.000000
-9223372036854775808

本篇关于《Golang中JSON编组和解组期间数字不匹配》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>