JSON编号在解组到接口后被切断

inn6fuwd  于 2023-05-19  发布在  其他
关注(0)|答案(2)|浏览(68)

因此,我有一个包含许多字段的JSON,我正在按照How effectively to change JSON keys的建议循环它,以删除一些我不需要的键。但是在删除之后,现有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}
yc0p9oo0

yc0p9oo01#

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

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}
jyztefdp

jyztefdp2#

这是因为默认情况下,encoding/json包将float64存储在JSON数字的接口值中。参见json。
要将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

相关问题