Go 语言中的 JSON 解析
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于 Web 服务和应用程序之间的数据传输。Go 语言提供了内置的 encoding/json 包来处理 JSON 数据。
使用 json.Unmarshal 解析 JSON
json.Unmarshal 函数用于将 JSON 数据解码到 Go 语言的数据结构中。它接受一个字节切片和一个指向结构体、切片或 map 的指针作为参数。
go
func NumUnmarshal(){
jsonStr:={"id":1,"name":"Jerry"}
var res map[string]interface{}
_ = json.Unmarshal([]byte(jsonStr), &res)
fmt.Printf("%T\n",res["id"])
i := res["id"].(int64)
fmt.Println(i)
}
在这个例子中,我们定义了一个 JSON 字符串 jsonStr,然后使用 json.Unmarshal 将其解析到一个 map[string]interface{} 类型的变量 res 中。这里需要注意的是,json.Unmarshal 函数的第二个参数是一个指向 res 的指针,这是因为 json.Unmarshal 需要修改 res 的值。
解析完成后,我们可以通过 res["id"] 来访问 JSON 中的 id 字段。由于 res 是一个 map[string]interface{},所以 res["id"] 的类型是 interface{}。为了将其转换为 int64 类型,我们使用了类型断言 res["id"].(int64)。这里需要注意的是,如果 id 字段的值不是一个整数,那么这个类型断言将会失败,程序会抛出一个运行时错误。
使用 json.NewDecoder 解析 JSON
json.NewDecoder 函数用于创建一个 JSON 解码器,它可以从一个 io.Reader 接口读取 JSON 数据并解码到 Go 语言的数据结构中。
go
func NumDecode(){
jsonStr:={"id":1,"name":"Jerry"}
var res map[string]interface{}
decoder := json.NewDecoder(bytes.NewReader([]byte(jsonStr)))
decoder.UseNumber()
_ = decoder.Decode(&res)
i,_ := res["id"].(json.Number).Int64()
fmt.Println(i)
}
在这个例子中,我们首先创建了一个 bytes.Reader 来读取 JSON 字符串 jsonStr,然后使用 json.NewDecoder 创建了一个解码器 decoder。这里我们调用了 decoder.UseNumber() 方法,这个方法告诉解码器在解析 JSON 时,如果遇到数字,应该将其解析为 json.Number 类型,而不是 float64 类型。这是因为 json.Number 可以精确地表示整数,而 float64 可能会因为精度问题导致整数的表示不准确。
接下来,我们使用 decoder.Decode(&res) 来解码 JSON 数据到 res 变量中。与 json.Unmarshal 类似,这里的 res 也必须是一个指向结构体、切片或 map 的指针。
解析完成后,我们可以通过 res["id"] 来访问 JSON 中的 id 字段。由于我们使用了 decoder.UseNumber(),所以 res["id"] 的类型是 json.Number。为了将其转换为 int64 类型,我们使用了 json.Number.Int64() 方法。这个方法会尝试将 json.Number 转换为 int64,如果转换成功,它会返回转换后的 int64 值和一个 nil 错误;如果转换失败,它会返回一个错误。
总结
这两种方法都可以用来解析 JSON 数据,具体使用哪种方法取决于你的需求。如果你需要从一个字节切片中解析 JSON,那么 json.Unmarshal 是一个合适的选择;如果你需要从一个 io.Reader 中读取并解析 JSON,那么 json.NewDecoder 是一个更好的选择。此外,如果你需要精确地处理整数,那么使用 json.NewDecoder 并调用 decoder.UseNumber() 方法是一个不错的主意。