golang json
2019-03-16
golang
json 序列化/反序列化规则
bool for JSON booleans
float64 for JSON numbers(包含 int,int64,int32,int16 ...)
string, for JSON strings (包含字符串,时间)
[]interface{}, for JSON arrays(数字,字符串,对象等组成的数组,json )
map[string]interface{}, for JSON objects
nil for JSON null
golang 为什么要有jsontag
由于golang使用大小作为是否导出属性,方法的定义的规则。 造成golang json Unmarshal 无法将小写开头的json的key解析到struct结构。 例如:
a := `{"a":2}`
type aStruct struct {
A int
a int
}
json Unmarshal 后, A/a 字段中都是空值。 在给结构的key 加上tag后就可以取出 小写字段的key
a := `{"a":2,"aa":4}`
type aStruct struct {
A int `json:"a"`
a int `json:"aa"` //小写属性加tag是无意义的。值解析不上的
}
golang 内置tag
omitempty:如果字段的值为空
(boolean as false, number as 0, nil pointer, a nil interface value, and any empty array, slice, map, or string)
在序列化时该字段不存
-:该字段在json 序列化/反序列忽律
string:将字段值在编码过程中转换成 JSON 中的字符串类型,只有当字段类型是 string, floating point, integer, or boolean 的情况下才会转换。
golang tag 作用
- 反序列化支持json小写key反写到struct 的key中
- 支持json中的key转化
```
type Login struct {
User string
json:"usr"
Password stringjson:"pwd"
}
### golang json 反序列一个key支持多种数据类型
由于golang 是一种强类型语言。struct对象的key类型是固定的。
但是在弱类型语言中对就不一样了。
例如:PHP (支持key为字符串)
如果 PHP array是空的时候,序列化出来是[]。
但是不为空的时候,序列化出来的是{"key":"value"}或者是["val1","val2"]
我们需要把 [] 当成 {} 处理。
这种情况我们可以使用重载UnmarshalJson的方法来实现
```golang
代码:
package main
import (
"encoding/json"
"fmt"
"strings"
)
type AField struct {
A map[string]interface{}
B []string
}
func (a *AField) UnmarshalJSON(b []byte) error {
str := strings.TrimSpace(string(b))
if str == "" || str == "[]" {
a.A = nil
return nil
}
if err := json.Unmarshal(b, &a.B); err == nil {
return nil
}
return json.Unmarshal(b, &a.A)
}
type tmpStruct struct {
A AField `json:"a"`
}
func main() {
strArr := `{"a":["b","b"]}`
strMap := `{"a":{"aa":"11"}}`
t1 := new(tmpStruct)
t2 := new(tmpStruct)
json.Unmarshal([]byte(strArr), t1)
json.Unmarshal([]byte(strMap), t2)
fmt.Println(fmt.Sprintf("%#v", t1))
fmt.Println(fmt.Sprintf("%#v", t2))
}
结果:
&main.tmpStruct{A:main.AField{A:map[string]interface {}(nil), B:[]string{"b", "b"}}}
&main.tmpStruct{A:main.AField{A:map[string]interface {}{"aa":"11"}, B:[]string(nil)}}