开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:结构体 map 切片序列化】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9738
结构体 map 切片序列化
内容介绍
一、json 的序列化
二、代码演示
一、json 的序列化
1.简介
json 序列化是指,将有 key-value 结构的数据类型(比如结构体、map、切片)序列化成 json 字符串的操作。
如果把go里面的数组、结构体、map、切片进行序列化可以得到对应的字符串
2.应用案例
这里介绍结构体、map 和切片的序列化,其它数据类型的序列化类似。
字符串也可以序列化,但是这个操作没有意义。
二、代码演示
1.结构体的序列化
package main
import (
"fmt"
"encoding/json"
//定义一个结构体
type Monster struct {
Name string
Age int
Birthday string
sal float64
skill string
}
func teststruct(){
//演示
对结构体进行演示首先去声明和创建结构体
monster := Monster{
Name :"牛魔王",//初始化
Age :500,
Birthday :"2011-11-11",
sal :8000.0,
skill :“牛魔拳”,
}
这就是一个结构体序列形式,下面将其序列化
最核心的序列化方法marshal
打开手册encoding/json的一个方法叫做Marshal
Marshal函数返回v的json编码
注意
func Marshal(v interface{})([]byte,erro)接受的是空的接口类型,也就是说任何一种数据类型都可以进行序列化,序列化后会返回byte切片,不是byte数组,如果序列化失败会返还erro,写成字符串还需要转化
//将monster 序列化
data, err := json.Marshal(&monster)
if err != nil {
fmt.Printf("序列化错误 err-%n\n", err)
//输出序列化后的结果
fmt.Printf("monster序列化后-%v\n", string(data))
//因为是一个data切片fmt.Printf("monster序列化后-%v",data)看不到内容,是一堆数字,所以要转string
}
func main() {
//演示将结构体,map ,切片进行序列化
teststruct( )
}
运行查看结果
将序列化的结果复制到站点
"Name ":"牛魔王",
"Age":500,
"Birthday" :"2011-11-11",
"Sal":8000.0,
"Skill":“牛魔拳”
2.map序列化
//定义一个map
var a map[string]interface{}
//使用map,需要make
a = make(map[string]interface{})
a["name"]="红孩儿"
a["age"] = 30
a["address"] = "洪崖洞"
//将a这个map进行序列化
//将monster序列化
data, err := json Marshal(a)
if err != nil{
fmt.Printf("序列化错误err=%v\n",err)
}
//输出序列化后的结果
fmt. printf("a map序列化后=%v\n",string(data))
key为name,age,adress序列化后顺序并不是与写的顺序保持一致,但是结果是正确的,map本身是按引用方式传递的直接写a就可以。同样会把序列化结果放到json中,返回的是byte切片,如果有错误会放到err中
3.切片序列化
//演示对切片进行序列化,这个切片[]map[string]interface{}
func testslice(){
var slice []map[string]interface{}
var ml map[string]interface{}
//使用map前,需要先make
m1 =make(map[string]interface{})
m1["name"] ="jack"
m1["age"] = "7"
m1["address"]="北京"
slice = append(slice, ml)
var m2 map[string]interface{}
//使用map前,需要先make
m2 = make(map[string]interface{})
m2["name"] ="tom"
m2["age"] ="20"
m2["address" ]="墨西哥"
slice = append(slice, m2)
//输出序列化后的结果
fmt.Printf("a map 序列化后-%v\n", string(data))
//将切片进行序列化操作
data, err := json.Marshal(slice)
if err != nil {
fmt.Printf("序列化错误err=%v\n",err)
}
//输出序列化后的结果
fmt.Printf("sliceJ序列化后=%v\n",string(data))
将切片序列化后可以看到为一个数组,因为有两个切片,两个切片直接用,隔开,json是key,val顺序不是很重要只要在[]内就可以,因为可以通过key区分究竟是哪个值
4.基本数据序列化
//对基本数据类型序列化
func testFloat64(){
var num1 float64 = 2345.67
//对num1进行序列化
data, err := json.Marshal(num1)
if err != nil {
fmt.Printf("序列化错误 err=%n\n"」 err)
//输出序列化后的结果
fmt.Printf("num1 序列化后=%v\n", string(data))
对普通类型序列化会变成什么样子?
普通数据本身没有key,val序列化后是否会发生变化,如果序列化出错会将err打印出来。演示未报错,可以序列化,但是序列化过后还是一个字符串,相当于将float64转成字符串。所以对基本数据类型进行序列化没有什么实际意义
m2["address" ]="墨西哥"中是interface放一个数组,查看序列化结果
m2["address" ]=[2]string{"墨西哥","夏威夷"}
[
{
"address":""北京",
"age":"7",
"name":"Jack"
},
{
"address":[
"墨西哥",
"夏威夷"
]
"age":"20"
"name":"Tom"
]