Json
概述:Json(JavaScript object Notation)是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。
Json是在2001年开始推广使用的数据格式,目前已经成为主流的数据结构。
Json易于机器解析和生成,并有效提升网络传播效率,通常程序在网络传输时会先将数据(结构体、map等)序列化成json字符串,到接收方得到json字符串时,再反序列化恢复成原来的数据类型。这种方式已然成为各个语言的标准。
在js语言中,一切都是对象。因此,任何的数据类型都可以通过json来表示,例如字符串、数字、对象、map、结构体等。
Json键值对是用来保存数据一种方式,键值对组合中的键名写在前面并用双引号包裹,使用冒号分隔,然后紧接着值。
Json的序列化
介绍:json序列化是指将有key-value结构的数据类型(比如结构体、map、切片)序列化成json字符串的操作。
代码实例:
package main
import (
"encoding/json"
"fmt"
)
type Monster struct {
Name string
Age int
Bir string
sal float32
skill string
}
func teststruct() {
monster := Monster{
Name: "牛魔王",
Age: 500,
Bir: "2011-11-11",
sal: 8000.0,
skill: "牛魔拳",
}
fmt.Println(monster)
data, err := json.Marshal(&monster)
if err != nil {
fmt.Println("序列号错误", err)
}
fmt.Println("序列化后:", string(data))
}
func testMap() {
var a map[string]interface{}
a = make(map[string]interface{})
a["name"] = "红孩儿"
a["age"] = 32
a["address"] = "洪崖洞"
data, err := json.Marshal(a)
if err != nil {
fmt.Println("序列号错误", err)
}
fmt.Println("序列化后:", string(data))
}
func testSlice() {
var slice []map[string]interface{}
var m1 map[string]interface{}
m1 = make(map[string]interface{}) m1["name"] = "tom"
m1["age"] = 23
m1["address"] = "us"
slice = append(slice, m1)
var m2 map[string]interface{}
m2 = make(map[string]interface{}) m2["name"] = "sam"
m2["age"] = 19
m2["address"] = "uk"
slice = append(slice, m2)
data, err := json.Marshal(slice)
if err != nil {
fmt.Println("序列号错误", err) } fmt.Println("序列化后:", string(data))
}
func testfloat() {
var num1 float32 = 2345.6
data, err := json.Marshal(num1)
if err != nil {
fmt.Println("序列号错误", err) } fmt.Println("序列化后:", string(data))
}
func main() {
teststruct()
testMap()
testSlice()
testfloat()
}
说明:# 对于结构体的序列化,如果我们希望序列化后的key的名字,又我们自己重新制定,那么可以给struct指定一个tag标签。
Json反序列化
介绍:json反序列化是指将json字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作
代码示例:package main
import (
"encoding/json"
"fmt"
)
type Monster1 struct {
Name string
Age int
Bir string
Sal float32
Skill string
}
func unmarshalStruct() {
str := " {"Name":"牛魔王","Age":500,"Bir":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}"
var monster Monster1
err := json.Unmarshal([]byte(str), &monster) if err != nil {
fmt.Printf("unmarshal err=%v", err)
}
fmt.Println("反序列化后1:", monster)
}
func unmarshalMap() {
str := " {"Name":"牛魔王","Age":500,"Bir":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}"
var monster map[string]interface{} //注意:反序列化map,不需要make,因为make操作被封装到Umarshal函数
err := json.Unmarshal([]byte(str), &monster) if err != nil {
fmt.Printf("unmarshal err=%v", err)
}
fmt.Println("反序列化后2:", monster)
}
func unmarshalSlice() {
str := " [{"address":"us","age":23,"name":"tom"},{"address":"uk","age":19,"name":"sam"}]\n"
var slice []map[string]interface{}
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Printf("unmarshal err=%v", err)
}
fmt.Println("反序列化后3:", slice)
}
func main() {
unmarshalStruct() unmarshalMap() unmarshalSlice()
}
心得体会: 在反序列化一个json字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。 如果json字符串是通过程序获得的,则不需要再对“转义处理。尽管json的标准库已经挺强大了,但是还有缺点性能不太高:标准库大量使用反射获取值,首先 Go 的反射本身性能较差,较耗费 CPU 配置;其次频繁分配对象,也会带来内存分配和 GC 的开销。