json 序列化
go 语言中序列化 json 数据使用 json.Marshal 方法,代码如下:
func main() {
mm := map[string]interface{}{
"name": "uccs",
"age": 12,
"extra": map[string]interface{}{
"phone": "12345678910",
},
}
bytes, _ := json.Marshal(mm)
fmt.Println(string(bytes))
}
如果说需要对 json 数据进行格式化输出,可以使用 json.MarshalIndent 方法,代码如下:
MarshalIndent 第一个参数是要序列化的数据,第二个参数是前缀,第三个参数是缩进字符json.MarshalIndent(mm, "", " ")
序列化结构体
序列化结构体的时候,需要注意以下 2 点:
结构体的字段必须是大写字母开头,否则无法序列化
可以使用 json tag 来指定序列化后的字段名
json tag 使用方式:
json:"name" 表示序列化后的字段名为 name
json:"Phone,omitempty" 表示序列化后的字段名为 phone,如果字段值为空,则不序列化
如果是指针形式的字段
字段值为空,则不序列化,例如下面的 Name 字段,不会被序列化,因为指针为 nil
字段值是空字符串,则序列化,例如下面的 Email 字段,会被序列化,因为指针不为 nil
type Person struct {
Name *string `json:"name,omitempty"`
Email *string `json:"email,omitempty"`
}
email := ""
p := Person{
Email: &email,
}
json:"age,string" 序列化时可以将数字变成字符串
json:"-" 序列化时忽略该字段
反序列化
go 反序列化使用 json.Unmarshal 方法,传入 json 字符串和结构体指针,代码如下:
func main() {
j := `{
"name": "uccs",
"age": 18,
"email": "",
"phone": "2222"
}`
var p Person
_ := json.Unmarshal([]byte(j), &p)
fmt.Println(p)
}
反序列化的时候,需要注意,传递空字符串和没有传递字段是没有区别的,都会被反序列化,例如上面的 Email 字段,传递空字符串和没有传递字段拿到的值都是一个空
如何区分传递空字符串和没有传递字段呢?
需要在定义结构体的时候使用指针类型,例如下面的 Email 字段,如果传递空字符串,则 Email 字段的值是一个地址,如果没有传递字段,则 Email 字段的值是 nil
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Email *string `json:"email"`
Phone string `json:"phone"`
}
j := `{
"name": "uccs",
"age": 18,
"phone": "2222"
}`
k := `{
"name": "uccs",
"age": 18,
"email": "",
"phone": "2222"
}`
var p1 Person
var p2 Person
_ := json.Unmarshal([]byte(j), &p1)
_ := json.Unmarshal([]byte(k), &p2)
fmt.Println(p1) // {uccs 18 <nil> 2222}
fmt.Println(p2) // {uccs 18 0xc000014140 2222}
所以我们可以通过判断 Email 字段是否为 nil 来区分传递空字符串和没有传递字段
fmt.Println(p1.Email == nil) // Email 是否为 nil 判断是否传递了 Email 字段
encoder
encoder 是一个 Writer 接口,可以用于写入文件
相比于 file.WriteString(string(bytes)) 方式,encoder 可以直接将结构体写入文件,并且是以流的方式写入
func main() {
p := Person{
Name: "xiaoming",
Age: 543251,
}
file, _ := os.Create("person.json")
defer file.Close()
encoder := json.NewEncoder(file)
encoder.SetEscapeHTML(true) // 转义 json 中的特殊字符
encoder.Encode(p)
}
decoder
decoder 是一个 Reader 接口,可以用于读取文件
decoder 是 encoder 的逆操作,可以从文件中读取 json 数据并且反序列化
func main() {
file, _ := os.Open("person.json")
defer file.Close()
decoder := json.NewDecoder(file)
p := Person{}
decoder.Decode(&p)
fmt.Println(p)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。