简体   繁体   English

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

[英]How to Unmarshal list of varied types without defaulting to float64

I have the following json data (from an external program, simplified a bit) I can't change the json format. 我有以下json数据(来自外部程序,简化了一点),我无法更改json格式。

[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. 我在使用Go打包时遇到了麻烦,主要是因为它是不同类型的列表。 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). 似乎要做的显而易见的事情是[] interface {},它可以工作,但是将其转换为float64会产生我无法处理的舍入错误(该数字是自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. 我可以通过两次解压缩来使它工作,例如[] interface {}和[] int64,但这显然会阻碍性能,并且我正在实时处理大量数据。 I tried using struct here because that would get treated as a map, not a list[] 我在这里尝试使用struct,因为它将被视为地图,而不是列表[]

Is there any way to either pass it the format of the data, or make it default to int64 instead of float64? 有什么方法可以将其传递为数据格式,或者将其默认设置为int64而不是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 ...) 即我知道上级列表的格式,并且映射的键是字符串,但是值可以是任何值(很痛苦,包括小数,我认为我唯一可以用来将它们解释为float的东西.. 。)

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) 解决方法(感谢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"])
}

根据此答案,您可以使用Decoder->和UseNumber或结构来代替直接解析值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM