记录golang序列化中使用的几个注意点
变量的大小写
go中根据首字母的大小写来确定可以访问的权限。如果首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用。包括接口、类型、函数和变量等。
可以简单的理解成,首字母大写是公有的,首字母小写是私有的
type Student struct {
name string
Id int
Major string
}
func main() {
testStruct := Student{
name: "zhangsan",
Id: 34254,
Major: "Computer Science",
}
jsonStr, err := json.Marshal(testStruct)
if err == nil {
fmt.Println("result: ",string(jsonStr))
}else {
fmt.Println("error occur", err)
}
}
执行的结果result: {"Id":34254,"Major":"Computer Science"}, 发现name根本没有被序列化进去;将首字母改成大写后,则成功序列化result: {"Name":"zhangsan","Id":34254,"Major":"Computer Science"}
type Student struct {
Name string
Id int
Major string
}
func main() {
testStruct := Student{
Name: "zhangsan",
Id: 34254,
Major: "Computer Science",
}
jsonStr, err := json.Marshal(testStruct)
if err == nil {
fmt.Println("result: ",string(jsonStr))
}else {
fmt.Println("error occur", err)
}
}
map反序列化精度损失
现象
下面代码执行的结果,会得到后面的输出,可以看到,id的大数字被unmarshal转化成float64类型,从而出现了精度缺失
a := `{"id":280123412341234123}`
fmt.Printf("a:%v\n", a)
para := make(map[string]interface{})
err := json.Unmarshal([]byte(a), ¶)
fmt.Printf("para:%v, err:%v\n", para, err)
id := int64(para["id"].(float64))
fmt.Printf("id:%v\n", id)
a:{"id":280123412341234123}
para:map[id:2.801234123412341e+17], err:<nil>
id:280123412341234112
原因
在解析int型数据的过程中,采取了float64来存储了数字
// convertNumber converts the number literal s to a float64 or a Number
// depending on the setting of d.useNumber.
func (d *decodeState) convertNumber(s string) (interface{}, error) {
if d.useNumber {
return Number(s), nil
}
f, err := strconv.ParseFloat(s, 64)
if err != nil {
return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)}
}
return f, nil
}
解决方案
使用decoder,不能直接unmarshal
func main() {
a := `{"id":280123412341234123}`
fmt.Printf("a:%v\n", a)
para := make(map[string]interface{})
decoder := json.NewDecoder(strings.NewReader(a))
decoder.UseNumber()
err := decoder.Decode(¶)
fmt.Printf("para:%v, err:%v\n", para, err)
id, err := para["id"].(json.Number).Int64()
fmt.Printf("id:%v, err:%v\n", id, err)
}

浙公网安备 33010602011771号