问题描述
我在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的输出?
解决方案1
您可以使用和 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?
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值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!