doujian0265 2014-11-25 14:27
浏览 38
已采纳

如何在不默认为float64的情况下解组各种类型的列表

I have the following json data (from an external program, simplified a bit) I can't change the json format.

[1416495600501595942, {"venue_id": 73, "message_type": "ABC", "sequence": 26686695}]

I'm having trouble unpacking it in Go, I think mostly because it's a list of disparate types. The obvious thing to do seems to be to do is []interface{}, which works, but in converts it to a float64, which produces a roundoff error that I can't deal with (the number is a timestamp since epoch in nanos).

I can get it to work by unpacking it twice, as []interface{} and []int64, but that's obviously going to hinder performance, and I'm processing large amounts of data in real time. I tried using struct here because that would get treated as a map, not a list[]

Is there any way to either pass it the format of the data, or make it default to int64 instead of float64? It's always going to be

[int64, map[string]interface{}]

ie I know the format of the upper level list, and that the keys of the map are strings, but the values could be anything (painfully, including decimals, which I think the only thing I can use to interpret them as is floats ...)

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    j := `[1416495600501595942, {"venue_id": 73, "message_type": "ABC", "sequence": 26686695}]`
    b := []byte(j)
    fmt.Println(j)
    var line []interface{}
    var ints []int64

    json.Unmarshal(b, &line)
    fmt.Println(line)
    // fmt.Println(line[0].(int64))  - this doesn't work
    fmt.Println(line[0].(float64))
    fmt.Println(int64(line[0].(float64)))

    json.Unmarshal(b, &ints)
    fmt.Println(ints)
}

Output is as follows:

[1416495600501595942, {"venue_id": 73, "message_type": "oKC", "sequence": 26686695}]
[1.416495600501596e+18 map[venue_id:73 message_type:oKC sequence:2.6686695e+07]]
1.416495600501596e+18
1416495600501595904
[1416495600501595942 0]

Solution (thanks to makpoc / dystroy)

package main

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

func main() {
    j := `[1416495600501595942, {"venue_id": 7.3, "message_type": "oKC", "sequence": 26686695}]`
    b := []byte(j)
    fmt.Println(j)
    var line []interface{}

    d := json.NewDecoder(bytes.NewBuffer(b))
    d.UseNumber()
        if err := d.Decode(&line); err != nil {
        panic(err)
    }
    fmt.Println(line[0])
    data := line[1].(map[string]interface{})
    fmt.Println(data["venue_id"])
    fmt.Println(data["sequence"])
}
  • 写回答

1条回答 默认 最新

  • doushan1863 2014-11-25 15:29
    关注

    According to this answer you can use Decoder -> and UseNumber or a struct instead of directly parsing the value.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行