Go:将JSON字符串转换为map[string]interface{}

5
我正在尝试使用map[string]interface{}类型创建Go中的JSON表示。我正在处理JSON字符串,但很难弄清如何避免JSON取消编组器自动将数字处理为float64。这会导致以下错误:
例如,"{'a': 9223372036854775807}" 应该是 map[string]interface{} = [a 9223372036854775807],但实际上它是map[string]interface{} = [a 9.2233720368547758088E18]
我搜索了如何使用json.Number来避免此问题,但我更喜欢使用以上指定的map类型。

3
JSON默认将所有数字转换为float64类型,如果想要将其转换为整数,则需要将其反序列化到一个带有整数值的目标中(例如,map[string]intstruct{ a int })。或者您可以接受它是一个浮点数,并将其简单地类型转换为整数。 - Kaedys
我知道Go的encoding/json默认使用float64作为json数字。如果类型转换适用于大int64值,那么类型转换将是最简单的解决方案。我猜我得编写自定义编组器或指定映射类型。谢谢。 - Steven
2个回答

4
Go语言中的json.Unmarshal(...)函数自动将JSON数字转换成float64类型。如果您想将数字解组成其他类型,则需要使用具有自定义反序列化器的自定义类型。无法强制反序列化器将自定义值反序列化为通用映射。
例如,以下是将“a”属性的值解析为big.Int的方法。
package main

import (
  "encoding/json"
  "fmt"
  "math/big"
)

type MyDoc struct {
  A BigA `json:"a"`
}

type BigA struct{ *big.Int }

func (a BigA) UnmarshalJSON(bs []byte) error {
  _, ok := a.SetString(string(bs), 10)
  if !ok {
    return fmt.Errorf("invalid integer %s", bs)
  }
  return nil
}

func main() {
  jsonstr := `{"a":9223372036854775807}`
  mydoc := MyDoc{A: BigA{new(big.Int)}}

  err := json.Unmarshal([]byte(jsonstr), &mydoc)
  if err != nil {
    panic(err)
  }

  fmt.Printf("OK: mydoc=%#v\n", mydoc)
  // OK: mydoc=main.MyDoc{A:9223372036854775807}
}

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接