Golang Json反序列化踩坑!

509 阅读1分钟

Golang Json反序列化踩坑!

因为开发需要,我将Json字符串反序列化成为Map,然后再把Map的Value断言成某种类型。
在原始字符串中,类似于1、2、3这样的整形数字,我理所当然地认为,它被反序列化之后,它的类型应该是Int,但实际断言却报错——它是float64?!

探秘Json原生库的源码

我发现了下面这段代码:

// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
//	bool, for JSON booleans
//	float64, for JSON numbers
//	string, for JSON strings
//	[]interface{}, for JSON arrays
//	map[string]interface{}, for JSON objects
//	nil for JSON null

在Golang的json Unmarshal规范中,Json和类型的对应关系是:

  1. 布尔值对应bool
  2. 数字对应float64
  3. 字符串对应string
  4. 数组对应[]interface{}
  5. 复杂对象对应map[string]interface{}
  6. null对应nil

看看下面这个例子:

package main

import (
        "encoding/json"
        "log"
)

var jsonstr = `
{
        "user_name": "ryan",
        "user_age": 20,
        "user_sex": "male"
}`

func main() {
        var user = make(map[string]interface{})
        err := json.Unmarshal([]byte(jsonstr), &user)
        if err != nil {
                panic(err)
        }
        log.Printf("%+v", user)

        age2, ok := user["user_age"].(int)
        if ok {
                log.Printf("int, user_age: %v", age2)
        }

        age1, ok := user["user_age"].(float64)
        if ok {
                log.Printf("float user_age: %v", age1)
        }
}