概述
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 key-value
JSON是2001年开始推广使用的数据格式,目前以及成为主流的数据格式。
JSON易于机器解析和生成,并有效的提升网络传输效率,通常程序在网络传输时会先将数据(结构体、map等)序列化成JSON字符串,接收方得到JSON字符串时,再反序列化恢复成原来的数据类型(结构体、map等)
JSON序列化
import “encoding/json”
json包实现了json对象的编解码,参见RFC 4627。Json对象和go类型的映射关系请参见Marshal和Unmarshal函数的文档。
参见”JSON and Go”获取本包的一个介绍:http://golang.org/doc/articles/json_and_go.html
func Marshal(v interface{}) ([]byte, error)
Marshal函数返回v的json编码。
主要对struct、map、slice的序列化,转化成JSON字符串的形式。
基本数据类型序列化意义不大
代码
// json 序列化
package main
import (
"encoding/json"
"fmt"
)
// 这就需要通过 tag 来转化大写的字段,同时又保证内部调用的时候可以暴露变量
// 反射原理
type People struct {
Name string `json:"name01"`
Age int `json:"age"`
Height float64 `json:"height"`
}
func testStruct() {
p1 := People{
Name: "tom",
Age: 18,
Height: 178.5,
}
data, err := json.Marshal(p1)
if err != nil {
fmt.Println("序列化失败", err)
} else {
fmt.Println("data = ", string(data)) // {"name01":"tom","age":18,"height":178.5}
}
}
func testMap() {
var dict map[string]interface{} = make(map[string]interface{})
dict["海贼王"] = "luffy"
dict["剑豪"] = "索隆"
fmt.Printf("dict类型: %T, 值:%v \n", dict, dict)
data, err := json.Marshal(dict)
if err != nil {
fmt.Println("序列化失败", err)
} else {
fmt.Println("data = ", string(data)) // {"剑豪":"索隆","海贼王":"luffy"}
}
}
func testSlice() {
var slice []map[string]interface{}
var m1 map[string]interface{} = make(map[string]interface{})
m1["name"] = "xixi"
m1["age"] = 7
var m2 map[string]interface{} = make(map[string]interface{})
m2["name"] = "haha"
m2["age"] = 8
m2["addr"] = [2]string{"北京", "上海"}
slice = append(slice, m1, m2)
data, err := json.Marshal(slice)
if err != nil {
fmt.Println("序列化失败", err)
} else {
fmt.Println("data = ", string(data)) // [{"age":7,"name":"xixi"},{"addr":["北京","上海"],"age":8,"name":"haha"}]
}
}
func testFloat64() {
var n1 float64 = 12.21
data, err := json.Marshal(n1)
if err != nil {
fmt.Println("序列化失败", err)
} else {
fmt.Println("data = ", string(data)) // 12.21
}
}
func main() {
// struct
testStruct()
// map
testMap()
// slice
testSlice()
// 基本数据类型序列化
// 对基本数据类型序列化 意义不大
testFloat64()
}
JSON反序列化
import “encoding/json”
func Unmarshal(data []byte, v interface{}) error
Unmarshal函数解析json编码的数据并将结果存入v指向的值。
Unmarshal和Marshal做相反的操作,必要时申请映射、切片或指针,
注意
在反序列化一个json字符串时,要确保反序列化后的数据类型和序列化前的数据类型一致
代码
// json 反序列化
package main
import (
"encoding/json"
"fmt"
)
type People struct {
Name string `json:"name01"`
Age int `json:"age"`
Height float64 `json:"height"`
}
func unMarshalStruct() {
var jsonStr string = "{\"name01\":\"tom\",\"age\":18,\"height\":178.5}"
var p1 People
// 要传入 &p1 指针类型,要写入的变量实例(可修改)
// 用 &p1 接收反序列化后的结果
err := json.Unmarshal([]byte(jsonStr), &p1)
if err != nil {
fmt.Println("反序列化失败", err)
} else {
fmt.Println("p1 = ", p1) // {tom 18 178.5}
}
}
// 测试序列化和反序列化
func testMap() string {
var dict map[string]interface{} = make(map[string]interface{})
dict["海贼王"] = "luffy"
dict["剑豪"] = "索隆"
fmt.Printf("dict类型: %T, 值:%v \n", dict, dict)
data, err := json.Marshal(dict)
if err != nil {
fmt.Println("序列化失败", err)
} else {
fmt.Println("data = ", string(data)) // {"剑豪":"索隆","海贼王":"luffy"}
}
return string(data)
}
func unMarshalMap() {
// var jsonStr string = "{\"剑豪\":\"索隆\",\"海贼王\":\"luffy\"}"
var jsonStr string = testMap()
var dict map[string]interface{}
// 注意: 反序列化map不需要 make 操作
// make 操作被封装到 json.Unmarshal() 里面
err := json.Unmarshal([]byte(jsonStr), &dict)
if err != nil {
fmt.Println("反序列化失败", err)
} else {
fmt.Println("dict = ", dict) // map[剑豪:索隆 海贼王:luffy]
}
}
func unMarshalSlice() {
var jsonStr = "[{\"age\":7,\"name\":\"xixi\"}," +
"{\"addr\":[\"北京\",\"上海\"],\"age\":8,\"name\":\"haha\"}]"
var slice []map[string]interface{}
// 同样不需要 make
err := json.Unmarshal([]byte(jsonStr), &slice)
if err != nil {
fmt.Println("反序列化失败", err)
} else {
fmt.Println("slice = ", slice) // [map[age:7 name:xixi] map[addr:[北京 上海] age:8 name:haha]]
}
}
func main() {
unMarshalStruct()
unMarshalMap()
unMarshalSlice()
}