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

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

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

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

場景示例

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

package main

import (
	"encoding/json"
	"fmt"
)

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

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

輸出:

【1】原始寫入 int64:
type=int64, value=7587721483007868979

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

JSON 序列化

接下來我們將這個 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 對 int64 的處理是安全的,大整數(shù)不會丟失精度。

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

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

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)庫 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)不再精確,丟失了最后幾位。

對比差值

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

輸出:

【5】對比:
是否相等: false
差值: 79

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

問題分析

原因總結(jié)

1.Go 的 encoding/jsonmap[string]interface{} 反序列化時:

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

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

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

解決方案

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

extra["oldTask"] = fmt.Sprintf("%d", oldTaskInt64)
  • JSON 序列化后:"oldTask":"7587721483007868979"
  • 寫入數(shù)據(jù)庫 / MQ / ES 時不會丟精度
  • 讀取時再用 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 反序列化會直接解析為 int64

結(jié)論

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

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

解決方案:

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

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

相關(guān)文章

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

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

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

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

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

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

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

    一文掌握Golang模糊測試

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

    Go官方限流器的用法詳解

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

    2026年Go語言開發(fā)中沒有它就不行的10個庫總結(jié)

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

    解決go語言ssh客戶端密碼過期問題

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

    Go語言開發(fā)前后端不分離項目詳解

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

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

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

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

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

最新評論

美姑县| 积石山| 平定县| 淳安县| 霍州市| 汝阳县| 获嘉县| 剑河县| 马鞍山市| 富锦市| 宾阳县| 灌云县| 岳普湖县| 甘德县| 松阳县| 东阿县| 南澳县| 锦屏县| 沾益县| 扎囊县| 白玉县| 松滋市| 大田县| 砀山县| 台前县| 宁海县| 龙陵县| 法库县| 沾益县| 临沭县| 武邑县| 宁蒗| 原阳县| 广宗县| 祥云县| 莒南县| 定兴县| 蒙山县| 隆化县| 永修县| 安岳县|