go语言学习之json操作。
go数据类型和json的类型对应关系图
- bool类型 – JSON的Boolean
- 整数,浮点数等数值类型 – JSON的Number
- string – JSON的字符串(带”“引号)
- struct – JSON的Object (再根据各个成员的类型递归打包)
- 数组或切片 – JSON的Array
- []byte – 会先进行base64编码然后转换为JSON字符串
- map – JSON的Object。key必须是string
- interface{} – 按照内部的实际类型进行转换
- nil – JSON的null
- channel,func等类型 – 返回UnsupportedTypeError
Marshal和Unmarshal函数
常见的Marshal使用方式是,结构体转json
type Student struct {
Name string `json:"name"` //通过标签的方式配置struck变量与json key对应关系
Age int `json:"age"`
Sex string `json:"sex"`
}
func main() {
var stu = Student{"dtc", 22, "boy"}
//将结构体封装成json格式,并返回[]byte
j, err := json.Marshal(stu)
if err != nil {
fmt.Errorf("Marshal Error %v", err)
}
fmt.Println(string(j))
}
output: {"Name":"dtc","Age":22,"Sex":"boy"}
结构体中大写开头的变量才可以被json处理(当未使用标签的时候),小写开头不会被处理。
type Student struct {
Name string
AgE int // json key `age`无法识别
sex string // 开头小写无法识别
high string `json:"-"` // 设置-标签,忽略这个字段
}
通过UnMarshal解析json为struct
type Student struct {
Name string `json:"stu_name"`
Age int `json:"stu_age"`
Sex string `json:"stu_sex"`
}
func main() {
str := []byte(`{"stu_name":"hiehie","stu_age":22,"stu_sex":"girl"}`)
var stu Student
err := json.Unmarshal(str, &stu)
if err != nil {
fmt.Println(err)
}
fmt.Println(stu)
}
output: {hiehie 22 girl}
转换接口
Marshal(v interface{}) 在调用时,会先判断v参数是否实现json.Marshaler或者 encoding.Marshaler 接口,如果满足,则会调用这两个接口来进行转换(如果两个都满足,优先调用json.Marshaler)。这两个接口定义如下:
// json.Marshaler
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
// encoding.TextMarshaler
type TextMarshaler interface {
MarshalText() (text []byte, err error)
}
UnMarshal(v interface{})在调用时,会先判断参数v是否实现json.Unmarshaler和encoding.TextUnmarshaler来调用相应函数(若两个函数都存在,则优先调用UnmarshalJSON)。这两个接口定义如下:
// json.Unmarshaler
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
// encoding.TextUnmarshaler
type TextUnmarshaler interface {
UnmarshalText(text []byte) error
}
可以通过对结构体实现marshalJSON和UnmarshalJSON接口实现自己编码解码。
参考链接
https://studygolang.com/articles/10581
https://blog.csdn.net/u011304970/article/details/70769949
总结
使用go json时注意使用标签防止json解析错误。
结构体变量定义尽量规范。