JSON 数字在解组到接口后被切断

问题描述 投票:0回答:2

所以我有一个包含很多字段的 JSON,我正在按照建议循环遍历它 如何有效地更改 JSON 键 删除一些我不需要的键。但是删除之后,现有JSON的原始值发生了变化,其中一些似乎是浮点数,我做了一个演示来展示它。

我怎样才能改变这种行为?是

interface{}
引起的问题吗?为什么
1684366653200744506
被截断为
1684366653200744400

谢谢!

https://go.dev/play/p/X2auWqWB2fL

供参考,输出JSON更改为1684366653200744400

2009/11/10 23:00:00 1684366653200744448.000000
2009/11/10 23:00:00 map[timestamp:1.6843666532007444e+18]
2009/11/10 23:00:00 json Marshal from maps of key string and value interface to batch json for insert to DB
2009/11/10 23:00:00 {"timestamp":1684366653200744400}
json go precision
2个回答
1
投票

我建议创建一个类型并删除不需要的字段。

package main

import (
    "encoding/json"
    "log"
)

type A struct {
    Timestamp int64 `json:"timestamp"`
}

func main() {
    jsonBatch := `{"timestamp":1684366653200744506, "todelete":"string value or boolean value"}`
    i := A{}
    if err := json.Unmarshal([]byte(jsonBatch), &i); err != nil {
        log.Println("json UnMarshal from batch json failed")
        log.Println(err)
    }
    dbJsonBatch, err := json.Marshal(i)
    if err != nil {
        log.Println("json Marshal from batch json failed")
        log.Println(err)
    }
    log.Println("json Marshal from maps of key string and value interface to batch json for insert to DB")
    log.Println(string(dbJsonBatch))
}

这打印

2009/11/10 23:00:00 json Marshal from maps of key string and value interface to batch json for insert to DB
2009/11/10 23:00:00 {"timestamp":1684366653200744506}

0
投票

这是因为默认情况下,

encoding/json
包将
float64
存储在 JSON 数字的接口值中。参见 json.Unmarshal:

为了将 JSON 解组为接口值,Unmarshal 将其中一个存储在接口值中:

  • bool,用于 JSON 布尔值
  • float64,用于 JSON 数字
  • ...

您可以创建一个解码器并调用 (*Decoder).UseNumber 来改变行为:

jsonBatch := `{"timestamp":1684366653200744506, "todelete":"string value or boolean value"}`
dec := json.NewDecoder(strings.NewReader(jsonBatch))
dec.UseNumber()
var i interface{}
if err := dec.Decode(&i); err != nil {

https://go.dev/play/p/ZjWB-NfiEQL.

© www.soinside.com 2019 - 2024. All rights reserved.