代码改变世界

golang标准库序列化反序列化 json + 第三方msgpack

2023-03-05 09:12  dribs  阅读(311)  评论(0编辑  收藏  举报

序列化:将内存中对象存储下来,把它变成一个个字节,转为二进制数据

反序列化:将文件的一个个字节恢复成内存中队形。从二进制数据中恢复

字符序列化:json xml

二进制序列化: protocol buffers 、messagepak等

 

package main

import (
	"encoding/json"
	"fmt"
	"github.com/vmihailenco/msgpack/v5"
)

type Persion struct {
	Name string `json:"nnn" msgpack:"name"` //标签 json使用nnn mespack使用name
	Age  int    `json:"age"`
}

func example1() {
	//序列化 go数据--->json协议--->字符串
	//json本质上是字符串 int 100 =>json 是string 100 这是三个字符 \x31 \x30 \x30(16进制字符表达) x30(16进制整数表达法)
	var data = []any{
		100, 2.5, true, false, nil, "abc",
		[...]int{97, 98, 99},
		map[string]int{"aaaa": 1111, "bbbb": 2222}, //json要求key必须是字符串
	}
	var target = make([][]byte, 0, len(data)) //b的类型是[]byte,放所有的b,定义成[][]byte
	for i, v := range data {
		b, err := json.Marshal(v)
		if err != nil {
			continue
		}
		target = append(target, b)
		//0: int 100,[]uint8 [49 48 48] 100
		fmt.Printf("%d: %T %[2]v,%T %[3]v %s\n", i, v, b, string(b))
	}
	fmt.Println(json.Marshal(data)) // 字符串 91 49 48 48 44 50 46 53 44 116 114 117 101 44 102 97 108 115 101 44 110 117 108 108 44 34 97 98 99 34 93
	fmt.Println(target)             //切片[[49 48 48] [50 46 53] [116 114 117 101] [102 97 108 115 101] [110 117 108 108] [34 97 98 99 34]]

	//反序列化
	println("=====反序列化======")
	for j, v := range target {
		var i any
		err := json.Unmarshal(v, &i) //传指针 不然外面的i无法修改
		if err != nil {
			continue
		}
		//0:[]uint8 [49 48 48], float64 100  此时还原回去 但100的类型变了
		//map[string]interface {} map[aaaa:1111 bbbb:2222]
		fmt.Printf("%d:%T %[2]v, %T %[3]v\n", j, v, i)
	}

}
func example2() {
	var data = Persion{
		Name: "Tome",
		Age:  18,
	}
	b, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}
	//main.Persion {Name:Tome Age:18}; []uint8 [123 34 110 110 110 34 58 34 84 111 109 101 34 44 34 97 103 101 34 58 49 56 125]
	fmt.Printf("%T %+[1]v; %T %[2]v\n", data, b)
	fmt.Println(string(b)) //{"Name":"Tome","Age":18} Persion类型没了
	//知道实例类型的时候
	var p1 Persion
	err = json.Unmarshal(b, &p1)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%T %+[1]v\n", p1) //main.Persion {Name:Tome Age:18}
	//不知道实例类型的时候
	var i interface{}
	err = json.Unmarshal(b, &i)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%T %+[1]v\n", i) //map[string]interface {} map[Age:18 Name:Tome]

	//msgpack
	fmt.Println("========msgpack=========")
	b, err = msgpack.Marshal(data) //返回的是二进制的[]byte json返回的是字符的[]byte编码
	if err != nil {
		panic(err)
	}
	fmt.Printf("%T, %+[1]v\n", b) //[]uint8, [130 164 110 97 109 101 164 84 111 109 101 163 65 103 101 18]
	//反序列化
	//知道目标类型
	var j Persion
	err = msgpack.Unmarshal(b, &j)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("%T %+[1]v\n", j) //main.Persion {Name:Tome Age:18}
}

func main() {
	//example1()
	example2()
}