当前位置: 首页 > 面试题库 >

在Go中解析json时保留int64值

元修然
2023-03-14
问题内容

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

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))

}

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

转到上面代码的游乐场


问题答案:

解决方案1

您可以使用Decoder和UseNumber解码您的号码而不会丢失:

Number类型的定义如下:

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

这意味着您可以轻松地将其转换:

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
}

解决方案2

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

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
}

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

警告

如果您使用JSON,因为您的应用程序部分是在JavaScript中的,请注意:JavaScript没有64位整数,只有一个数字类型,即IEEE754双精度浮点数。因此,您将无法使用标准解析功能在JavaScript中解析此JSON而不会丢失。



 类似资料:
  • 问题内容: 我正在尝试在Go中解析json流。我创建了一个简化的示例: 这会给我 我在sql包中发现了一个可为null的int64 ,但是json似乎无法处理它。 json是否可以处理可为null的int64类型?如果可能的话,我会对将JSON null 转换为-1或MinValue 感到满意。 谢谢您的投入,Fabian 问题答案: 只需使用一个。指针可以为nil,也可以指向具有关联值的int6

  • 问题内容: 我们有事务日志文件,其中每个事务都是JSON格式的一行。我们经常需要获取数据的选定部分,执行一次时间转换,然后以特定格式将结果馈送到另一个系统中。我编写了一个Python脚本,可以根据需要执行此操作,但是我希望Go可以更快,并且可以给我一个开始学习Go的机会。因此,我写了以下内容: 编译时没有任何抱怨,但是令我惊讶的是缺乏性能改进。为了进行测试,我将2,000,000行日志放入tmpf

  • 我收到一个YAML文件,我使用snakeyaml引擎解析(对于YAML 1.2)。 然后我使用GSON将其转换为JsonObject。 我们的目标是运行这个YAML,对照已知的数据模型检查它。如果字段不同,必填字段丢失等,我必须为每个字段返回一个错误。我们的目标是找到某种方法来包含原始YAML中问题字段的行号,但是当我通过JSON进行验证时,遇到错误时,我不知道原始行号。我很好奇,是否有一些简单的

  • 问题内容: 我想解析Go中的JSON对象,但想为未指定的字段指定默认值。例如,我具有struct类型: A,B和C的默认值分别是“ a”,“ b”和“ c”。这意味着当我解析json时: 我想得到的结构: 使用内置包可以吗?否则,是否有任何具有此功能的Go库? 问题答案: 使用encoding / json可以实现:调用时,不需要给它一个空结构,可以给它一个默认值。 例如: 在Go操场上运行此示例

  • 问题内容: 使用该包可以很容易地解析如下对象。 我面临的问题是从服务器返回多个命令,如下所示: 无法使用以下代码进行解析。 我正在尝试解析Common Crawl数据(请参阅示例)。 我怎样才能做到这一点? 问题答案: 假设您的输入确实是一系列有效的JSON文档,请使用json.Decoder对其进行解码: 游乐场:https://play.golang.org/p/ANx8MoMC0yq 如果您

  • 问题内容: 我有一个带有字段的结构类型。 在代码的某个时刻,我想声明一个字面值(例如,当我知道值应该为0或指向0时,您就知道我的意思了) …除非这不起作用 所以我尝试这个 …但是这也不起作用 我该怎么做呢?我唯一能想到的解决方案是使用占位符变量 注意: 当使用 int而不是时, 语法可以 正常 工作 。 编辑:不,不。为此表示歉意。 编辑: 显然,我的问题含糊不清。我正在寻找一种方式来 字面上状态