在Go中解析json时保留int64值 [英] preserve int64 values when parsing json in Go

查看:152
本文介绍了在Go中解析json时保留int64值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Go中处理一个json POST,其中包含一个包含64位整数的对象数组。当使用json.Unmarshal时,这些值似乎转换为float64,这不是很有用。

  body:= [] (`{tags:[{id:4418489049307132905},{id:4418489049307132906}]}`)

var dat map [string] interface {}
if err:= json.Unmarshal(body,& dat); err!= nil {
panic(err)
}

tags:= dat [tags]。([] interface {})

为i,tag:= range tags {

fmt.Println(tag:,i,id:,tag。(map [string] interface {})[id] 。(int64))

}

有什么办法可以保留原始int64在json.Unmarshal的输出?



去上面代码的Playground

解决方案

解决方案1 ​​



您可以使用解码器和<一个href =http://golang.org/pkg/encoding/json/#Decoder.UseNumber =noreferrer> UseNumber 解码你的电话号码而不会丢失:



Number 类型定义如下:

  //数字表示JSON数字文字。 
类型数字字符串

这意味着您可以轻松转换它:

 包主
$ b导入(
编码/ json
fmt
字节
strconv


func main(){
body:= [] byte({\tags\:[ {\id \:4418489049307132905},{\id \:4418489049307132906}]})
dat:= make(map [string] interface {})
d:= json.NewDecoder(bytes.NewBuffer(body))
d.UseNumber()
if err:= d.Decode(& dat); err!= nil {
panic(err)
}
tags:= dat [tags]。([] interface {})
n:= tags [0]。 (map [string] interface {})[id]。(json.Number)
i64,_:= strconv.ParseUint(string(n),10,64)
fmt.Println i64)//打印4418489049307132905
}

解决方案2



您也可以解码为适合您需求的特定结构:

 包主要

导入(
encoding / json
fmt


类型struct {
Tags [] map [string] uint64 //tags
}

func main(){
body:= [] byte({\tags\ :[{\id \:4418489049307132905},{\id \:4418489049307132906}]})
var a A
if err:= json.Unmarshal(body ,& a); err!= nil {
panic(err)
}
fmt.Println(a.Tags [0] [id])// logs 4418489049307132905
}

就我个人而言,我通常更喜欢这种感觉更加结构化且易于维护的解决方案。

注意



如果您使用JSON,在JavaScript中:JavaScript没有64位整数,但只有一个数字类型,即IEEE754双精度浮点数。因此,您无法使用标准解析函数在JavaScript中解析此JSON。


I'm processing a json POST in Go that contains an array of objects containing 64bit integers. When using json.Unmarshal these values seem to be converted to a float64 which isn't very helpful.

body := []byte(`{"tags":[{"id":4418489049307132905},{"id":4418489049307132906}]}`)

var dat map[string]interface{}
if err := json.Unmarshal(body, &dat); err != nil {
    panic(err)
}

tags := dat["tags"].([]interface{})

for i, tag := range tags {

    fmt.Println("tag: ", i, " id: ", tag.(map[string]interface{})["id"].(int64))

}

Is there any way to preserve the original int64 in the output of json.Unmarshal?

Go Playground of above code

解决方案

Solution 1

You can use a Decoder and UseNumber to decode your numbers without loss :

The Number type is defined like this :

// A Number represents a JSON number literal.
type Number string

which means you can easily convert it :

package main

import (
    "encoding/json"
    "fmt"
    "bytes"
    "strconv"
)

func main() {
    body := []byte("{\"tags\":[{\"id\":4418489049307132905},{\"id\":4418489049307132906}]}")
    dat := make(map[string]interface{})
    d := json.NewDecoder(bytes.NewBuffer(body))
    d.UseNumber()
    if err := d.Decode(&dat); err != nil {
        panic(err)
    }
    tags := dat["tags"].([]interface{})
    n := tags[0].(map[string]interface{})["id"].(json.Number)
    i64, _ := strconv.ParseUint(string(n), 10, 64)
    fmt.Println(i64) // prints 4418489049307132905
}

Solution 2

You can also decode into a specific structure tailored to your needs :

package main

import (
    "encoding/json"
    "fmt"
)

type A struct {
    Tags []map[string]uint64 // "tags"
}

func main() {
    body := []byte("{\"tags\":[{\"id\":4418489049307132905},{\"id\":4418489049307132906}]}")
    var a A
    if err := json.Unmarshal(body, &a); err != nil {
        panic(err)
    }
    fmt.Println(a.Tags[0]["id"]) // logs 4418489049307132905
}

Personally I generally prefer this solution which feels more structured and easier to maintain.

Caution

A small note if you use JSON because your application is partly in JavaScript : JavaScript has no 64 bits integers but only one number type, which is the IEEE754 double precision float. So you wouldn't be able to parse this JSON in JavaScript without loss using the standard parsing function.

这篇关于在Go中解析json时保留int64值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆