簡體   English   中英

Golang中json Marshall和Unmarshall的數字不一致

[英]Inconsistency in numbers between json Marshall and Unmarshall in Golang

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM