[英]How to Unmarshal list of varied types without defaulting to float64
我有以下json数据(来自外部程序,简化了一点),我无法更改json格式。
[1416495600501595942, {"venue_id": 73, "message_type": "ABC", "sequence": 26686695}]
我在使用Go打包时遇到了麻烦,主要是因为它是不同类型的列表。 似乎要做的显而易见的事情是[] interface {},它可以工作,但是将其转换为float64会产生我无法处理的舍入错误(该数字是自nanos中的纪元以来的时间戳) )。
我可以通过两次解压缩来使它工作,例如[] interface {}和[] int64,但这显然会阻碍性能,并且我正在实时处理大量数据。 我在这里尝试使用struct,因为它将被视为地图,而不是列表[]
有什么方法可以将其传递为数据格式,或者将其默认设置为int64而不是float64吗? 永远都是
[int64, map[string]interface{}]
即我知道上级列表的格式,并且映射的键是字符串,但是值可以是任何值(很痛苦,包括小数,我认为我唯一可以用来将它们解释为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)
}
输出如下:
[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]
解决方法(感谢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.