key-value
1 json的序列化
json的序列化是指,将现有的key-value结构的数据类型(比如结构体、map、切片)序列化成json字符串的操作。
package main
import (
"fmt"
"encoding/json"
)
// 定义一个结构体
type Monster struct {
// 如果希望json过后字段的名称,需要打一个tag
Name string `json:"name"` // 通过反射机制实现的
Age int `json:"age"`
Birthday string
Sal float64
Skill string
}
func testStruct() {
// 声明结构体实例
monster := Monster{
Name: "牛魔王",
Age: 500,
Birthday: "2011-11-11",
Sal: 10000.0,
Skill: "牛头拳",
}
// 将monster序列化
data, err := json.Marshal(&monster)
if err != nil {
fmt.Printf("序列化错误 = %v\n", err)
}
// 输出序列化后的结果
fmt.Printf("monster序列化后 = %v\n", string(data)) // 由于data是bate切片,所以需要转换成字符串
}
func testMap() {
// 定义一个map
var a map[string]interface{}
// 使用map,需要make
a = make(map[string]interface{})
a["name"] = "红孩儿"
a["age"] = 200
a["address"] = "洪崖洞"
// 将map序列化
data, err := json.Marshal(a) // 由于a map本身就是一个指针,所以不需要加引用地址的符号 &
if err != nil {
fmt.Printf("序列化错误 = %v\n", err)
}
// 输出序列化后的结果
fmt.Printf("a map序列化后 = %v\n", string(data))
}
// 对切片进行序列化
func testSlice() {
var slice []map[string]interface{}
var m1 map[string]interface{}
m1 = make(map[string]interface{})
m1["name"] = "jack"
m1["age"] = 7
m1["address"] = "天津"
slice = append(slice, m1)
var m2 map[string]interface{}
m2 = make(map[string]interface{})
m2["name"] = "merry"
m2["age"] = 30
m2["address"] = [2]string{"北京", "墨西哥"}
slice = append(slice, m2)
// 将切片序列化
data, err := json.Marshal(slice) // 由于a map本身就是一个指针,所以不需要加引用地址的符号 &
if err != nil {
fmt.Printf("序列化错误 = %v\n", err)
}
// 输出序列化后的结果
fmt.Printf("slice序列化后 = %v\n", string(data))
}
// 对基本数据类型序列化
func testFloat64() {
var num1 float64 = 1233.45
data, err := json.Marshal(num1) // 由于a map本身就是一个指针,所以不需要加引用地址的符号 &
if err != nil {
fmt.Printf("序列化错误 = %v\n", err)
}
// 输出序列化后的结果
fmt.Printf("num1序列化后 = %v\n", string(data))
}
func main() {
// (1)将结构体进行序列化
testStruct() // monster序列化后 = {"name":"牛魔王","age":500,"Birthday":"2011-11-11","Sal":10000,"Skill":"牛头拳"}
// (2)将map进行序列化
testMap() // a map序列化后 = {"address":"洪崖洞","age":200,"name":"红孩儿"}
// (3)将切片进行序列化
testSlice() // slice序列化后 = [{"address":"天津","age":7,"name":"jack"},{"address":["北京","墨西哥"],"age":30,"name":"merry"}]
// (4)对基本数据类型序列化
testFloat64() // num1序列化后 = 1233.45
// 可以去 json.cn 网站上对json序列进行解析,看是否正确
}
2 json的反序列化
json的反序列化是指将json字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作。
package main
// 反序列化
import (
"fmt"
"encoding/json"
)
// 定义一个结构体
type Monster struct {
Name string
Age int
Birthday string
Sal float64
Skill string
}
// 将json字符串,反序列化成struct
func unmarshalStruct() {
// str在实际开发项目中是通过网络传输获取到,或者是读取文件获取到
str := "{\"name\":\"牛魔王\",\"age\":500,\"Birthday\":\"2011-11-11\",\"Sal\":10000,\"Skill\":\"牛头拳\"}"
// 定义一个Monster实例
var monster Monster
err := json.Unmarshal([]byte(str), &monster) // 这里需要注意,反序列化时候需要将str转成byte数组
if err != nil {
fmt.Printf("unmarshal err = %v\n", err)
}
fmt.Printf("反序列化后 monster = %v monster.Name=%v\n", monster, monster.Name)
}
// 反序列化map
func unmarshalMap() {
str := "{\"address\":\"洪崖洞\",\"age\":200,\"name\":\"红孩儿\"}"
// 定义一个map
var a map[string]interface{}
// 反序列化不需要make,底层会自动make
err := json.Unmarshal([]byte(str), &a)
if err != nil {
fmt.Printf("unmarshal err = %v\n", err)
}
fmt.Printf("反序列化后 a = %v\n", a)
}
// 将json字符串,反序列化成切片
func unmarshalSlice() {
str := "[{\"address\":\"天津\",\"age\":7,\"name\":\"jack\"}," +
"{\"address\":[\"北京\",\"墨西哥\"],\"age\":30,\"name\":\"merry\"}]"
// 定义一个Slice
var slice []map[string]interface{}
// 不需要make
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Printf("unmarshal err = %v\n", err)
}
fmt.Printf("反序列化后 a = %v\n", slice)
}
func main() {
// (1)反序列化mstruct结构体
unmarshalStruct() // 反序列化后 monster = {牛魔王 500 2011-11-11 10000 牛头拳} monster.Name=牛魔王
// (2)反序列化map
unmarshalMap() // 反序列化后 a = map[address:洪崖洞 age:200 name:红孩儿]
// (3)反序列化Slice
unmarshalSlice()
// 注意:
// 1、反序列化一个json字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。
// 2、如果json字符串是通过程序获取的,那么就不需要对双引号进行 \ 转移处理
}
3 Tips
package main
import (
"encoding/json"
"fmt"
"math"
)
type Data struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
func main() {
d1 := Data{
ID: math.MaxInt64,
Name: "RSQ",
}
b, err := json.Marshal(d1)
if err != nil {
fmt.Println("Json Marshal failed", err)
}
fmt.Println(string(b))
//{"id":"9223372036854775807","name":"RSQ"}
// 在结构体中给id打 string tag后,序列化时就会把其当作字符串来处理
// 这样可以保证大数据的id精准度
var d2 Data
str := `{"id":9223372036854775807,"name":"RSQ"}`
if err = json.Unmarshal([]byte(str), &d2); err != nil{
fmt.Println(err)
return
}
fmt.Printf("%#v\n", d2)
//main.Data{ID:9223372036854775807, Name:"RSQ"}
}