最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go JSON中序列化大整數(shù)精度丟失的問(wèn)題分析

 更新時(shí)間:2026年01月04日 09:18:24   作者:Kevin666  
當(dāng)存儲(chǔ)或傳輸 大整數(shù)(int64) 時(shí),往往會(huì)出現(xiàn)精度丟失的問(wèn)題,本文通過(guò)一個(gè)示例來(lái)詳細(xì)分析原因,并給出解決方案,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

在 Go 項(xiàng)目中,我們經(jīng)常使用 map[string]interface{} 來(lái)表示動(dòng)態(tài)字段,或者用 JSON 序列化對(duì)象存入數(shù)據(jù)庫(kù)、發(fā)送到 MQ。然而,當(dāng)存儲(chǔ)或傳輸 大整數(shù)(int64) 時(shí),往往會(huì)出現(xiàn)精度丟失的問(wèn)題。本文通過(guò)一個(gè)示例來(lái)詳細(xì)分析原因,并給出解決方案。

場(chǎng)景示例

假設(shè)我們有一個(gè)動(dòng)態(tài) Extra 字段,用于存儲(chǔ)一些擴(kuò)展信息,其中 oldTask 是一個(gè) int64 大整數(shù):

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// 模擬 Extra 字段
	extra := make(map[string]interface{})
	extra["oldTask"] = int64(7587721483007868979)

	fmt.Println("【1】原始寫(xiě)入 int64:")
	fmt.Printf("type=%T, value=%v\n\n", extra["oldTask"], extra["oldTask"])
}

輸出:

【1】原始寫(xiě)入 int64:
type=int64, value=7587721483007868979

在 Go 內(nèi)存中,extra["oldTask"] 正確保存了 int64 值。

JSON 序列化

接下來(lái)我們將這個(gè) map 序列化為 JSON 字符串(就像你在 BuildRiskPointsStrategy 中做的):

bytes, _ := json.Marshal(extra)
fmt.Println("【2】json.Marshal 后:")
fmt.Println(string(bytes), "\n")

輸出:

【2】json.Marshal 后:
{"oldTask":7587721483007868979}

Go 的 json.Marshal 對(duì) int64 的處理是安全的,大整數(shù)不會(huì)丟失精度。

JSON 反序列化到 map[string]interface{}

然而問(wèn)題出現(xiàn)了,當(dāng)我們反序列化 JSON 到 map[string]interface{} 時(shí):

var extra2 map[string]interface{}
_ = json.Unmarshal(bytes, &extra2)

fmt.Println("【3】json.Unmarshal 后:")
fmt.Printf("type=%T, value=%v\n\n", extra2["oldTask"], extra2["oldTask"])

輸出:

【3】json.Unmarshal 后:
type=float64, value=7587721483007869000

注意:

  • 反序列化后,extra2["oldTask"] 變成了 float64
  • 原始的 int64 值 7587721483007868979 精度丟失
  • 這是 Go 標(biāo)準(zhǔn)庫(kù) encoding/json 的默認(rèn)行為:map[string]interface{} 中的數(shù)字全部解析成 float64。

再轉(zhuǎn)回 int64

如果我們強(qiáng)行把它轉(zhuǎn)回 int64:

lost := int64(extra2["oldTask"].(float64))
fmt.Println("【4】float64 → int64 后:")
fmt.Println("value =", lost)

輸出:

【4】float64 → int64 后:
value = 7587721483007869000

可以看到,數(shù)字已經(jīng)不再精確,丟失了最后幾位。

對(duì)比差值

fmt.Println("【5】對(duì)比:")
fmt.Println("是否相等:", lost == int64(7587721483007868979))
fmt.Println("差值:", lost-int64(7587721483007868979))

輸出:

【5】對(duì)比:
是否相等: false
差值: 79

  • 原始值與反序列化后值不一致
  • 這就是“精度丟失”的根本原因

問(wèn)題分析

原因總結(jié)

1.Go 的 encoding/json 對(duì) map[string]interface{} 反序列化時(shí):

  • 所有數(shù)字默認(rèn)是 float64
  • float64 最大安全整數(shù)范圍是 -2^53 ~ 2^53

2.當(dāng) int64 值超出 2^53 時(shí),float64 表示不精確 → 精度丟失

Go 官方文檔說(shuō)明:JSON numbers without decimal points are decoded as float64 when the target is interface{}。

解決方案

方案 1:使用字符串存儲(chǔ)大整數(shù)

extra["oldTask"] = fmt.Sprintf("%d", oldTaskInt64)
  • JSON 序列化后:"oldTask":"7587721483007868979"
  • 寫(xiě)入數(shù)據(jù)庫(kù) / MQ / ES 時(shí)不會(huì)丟精度
  • 讀取時(shí)再用 strconv.ParseInt 轉(zhuǎn)回 int64

方案 2:使用json.Number解析

var extra2 map[string]interface{}
decoder := json.NewDecoder(bytes.NewReader(jsonBytes))
decoder.UseNumber() // 使用 json.Number 代替 float64
decoder.Decode(&extra2)
  • extra2["oldTask"] 類型是 json.Number
  • 可以安全轉(zhuǎn)成 int64string
num, _ := extra2["oldTask"].(json.Number).Int64()

方案 3:使用 struct 明確類型

type RiskExtra struct {
	OldTask int64 `json:"oldTask"`
}
  • 避免 map[string]interface{} → float64
  • JSON 反序列化會(huì)直接解析為 int64

結(jié)論

Go map[string]interface{} + JSON 是大整數(shù)丟失精度的高發(fā)場(chǎng)景

精度丟失的原因:JSON 默認(rèn)解析數(shù)字為 float64

解決方案:

  • 使用字符串存儲(chǔ)大整數(shù)
  • 使用 json.Number
  • 或者盡量使用 struct 明確類型

到此這篇關(guān)于Go JSON中序列化大整數(shù)精度丟失的問(wèn)題分析的文章就介紹到這了,更多相關(guān)Go JSON序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go用兩個(gè)協(xié)程交替打印100以內(nèi)的奇偶數(shù)的方法詳解

    Go用兩個(gè)協(xié)程交替打印100以內(nèi)的奇偶數(shù)的方法詳解

    這篇文章主要給大家詳細(xì)介紹了Go用兩個(gè)協(xié)程交替打印100以內(nèi)的奇偶數(shù)的示例代碼,文中給大家介紹了兩個(gè)實(shí)現(xiàn)方法,使用無(wú)緩沖的channel和設(shè)置GOMAXPROCS=1,介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • 從生成CRD到編寫(xiě)自定義控制器教程示例

    從生成CRD到編寫(xiě)自定義控制器教程示例

    這篇文章主要為大家介紹了從生成CRD到編寫(xiě)自定義控制器的教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Golang內(nèi)存泄漏場(chǎng)景以及解決方案詳析

    Golang內(nèi)存泄漏場(chǎng)景以及解決方案詳析

    golang中內(nèi)存泄露的發(fā)現(xiàn)與排查一直是來(lái)是go開(kāi)發(fā)者頭疼的一件事,下面這篇文章主要給大家介紹了關(guān)于Golang內(nèi)存泄漏場(chǎng)景以及解決的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 一文掌握Golang模糊測(cè)試

    一文掌握Golang模糊測(cè)試

    本文主要介紹了一文掌握Golang模糊測(cè)試,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Go官方限流器的用法詳解

    Go官方限流器的用法詳解

    限流器是提升服務(wù)穩(wěn)定性的非常重要的組件,本文主要介紹了Go官方限流器的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 2026年Go語(yǔ)言開(kāi)發(fā)中沒(méi)有它就不行的10個(gè)庫(kù)總結(jié)

    2026年Go語(yǔ)言開(kāi)發(fā)中沒(méi)有它就不行的10個(gè)庫(kù)總結(jié)

    Go語(yǔ)言以其簡(jiǎn)潔高效、并發(fā)安全、跨平臺(tái)編譯等特性,在后端服務(wù)、云原生、DevOps 工具等領(lǐng)域占據(jù)重要地位,這篇文章主要介紹了2026年Go語(yǔ)言開(kāi)發(fā)中沒(méi)有它就不行的10個(gè)庫(kù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-05-05
  • 解決go語(yǔ)言ssh客戶端密碼過(guò)期問(wèn)題

    解決go語(yǔ)言ssh客戶端密碼過(guò)期問(wèn)題

    這篇文章主要介紹了go語(yǔ)言ssh客戶端解決密碼過(guò)期問(wèn)題,本文給大家分享了解決的方法和原理,非常不錯(cuò),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Go語(yǔ)言開(kāi)發(fā)前后端不分離項(xiàng)目詳解

    Go語(yǔ)言開(kāi)發(fā)前后端不分離項(xiàng)目詳解

    這篇文章主要為大家介紹了Go語(yǔ)言開(kāi)發(fā)前后端不分離項(xiàng)目詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Go語(yǔ)言讀取文本文件的三種方式總結(jié)

    Go語(yǔ)言讀取文本文件的三種方式總結(jié)

    工作中時(shí)不時(shí)需要讀取文本,文本文件是最常見(jiàn)的文件類型。本文將利用Go語(yǔ)言從逐行、逐個(gè)單詞和逐個(gè)字符三個(gè)方法讀取文件,感興趣的可以了解一下
    2023-01-01
  • go語(yǔ)言版的ip2long函數(shù)實(shí)例

    go語(yǔ)言版的ip2long函數(shù)實(shí)例

    這篇文章主要介紹了go語(yǔ)言版的ip2long函數(shù),實(shí)例分析了Go語(yǔ)言實(shí)現(xiàn)的ip2long函數(shù)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02

最新評(píng)論

宝丰县| 正安县| 沂水县| 个旧市| 沙湾县| 新营市| 岢岚县| 安龙县| 赣榆县| 米泉市| 尼勒克县| 新兴县| 阳朔县| 遵义县| 遵义市| 鄯善县| 东明县| 南乐县| 宣恩县| 临沭县| 和顺县| 祁阳县| 谷城县| 隆安县| 澄城县| 东乡县| 韶关市| 临高县| 新巴尔虎右旗| 永川市| 石狮市| 恩施市| 灌云县| 德昌县| 永靖县| 宝兴县| 弥勒县| 海城市| 新闻| 商城县| 崇左市|