go结构体和json相互转换、序列化和反序列化

embedded/2025/2/9 12:14:03/

tags" href="/JSON.html" title=json>json_0">tags" href="/JSON.html" title=json>json简介

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。RESTfull Api 接口中返回的数据都是 tags" href="/JSON.html" title=json>json 数据。

Json 的基本格式如下:

tags" href="/JSON.html" title=json>json">{
"a": "Hello",
"b": "World"
}

稍微复杂的tags" href="/JSON.html" title=json>json:

tags" href="/JSON.html" title=json>json">{"result": [{"_id": "59f6ef443ce1fb0fb02c7a43","title": "笔记本电脑","status": "1","pic": "public\\upload\\UObZahqPYzFvx_C9CQjU8KiX.png","url": "12"},{"_id": "5a012efb93ec4d199c18d1b4","title": "第二个轮播图","status": "1","pic": "public\\upload\\f3OtH11ZaPX5AA4Ov95Q7DEM.png"},{"_id": "5a012f2433574208841e0820","title": "第三个轮播图","status": "1","pic": "public\\upload\\s5ujmYBQVRcLuvBHvWFMJHzS.jpg"},{"_id": "5a688a0ca6dcba0ff4861a3d","title": "教程","status": "1","pic": "public\\upload\\Zh8EP9HOasV28ynDSp8TaGwd.png"}]
}

结构体与 JSON tags" href="/XuLieHua.html" title=序列化>序列化

比如我们 Golang 要给 App 或者小程序提供 Api 接口数据,这个时候就需要涉及到结构体和Json 之间的相互转换。

Golang JSON tags" href="/XuLieHua.html" title=序列化>序列化是指把结构体数据转化成 JSON 格式的字符串,Golang JSON 的反tags" href="/XuLieHua.html" title=序列化>序列化是指把 JSON 数据转化成 Golang 中的结构体对象。

Golang 中 的 序 列 化 和 反 序 列 化 主 要 通 过 “encoding/tags" href="/JSON.html" title=json>json” 包 中 的 tags" href="/JSON.html" title=json>json.Marshal() 和tags" href="/JSON.html" title=json>json.Unmarshal()方法实现。

  1. 结构体对象转化成 Json 字符

代码示例:

package mainimport ("encoding/tags" href="/JSON.html" title=json>json""fmt"
)type Student struct {ID     intGender stringname   string //私有属性不能被 tags" href="/JSON.html" title=json>json 包访问Sno    string
}func main() {var s1 = Student{ID: 1, Gender: "男", name: "李四", Sno: "s0001"}fmt.Printf("%#v\n", s1)var s, _ = tags" href="/JSON.html" title=json>json.Marshal(s1)tags" href="/JSON.html" title=json>jsonStr := string(s)fmt.Println(tags" href="/JSON.html" title=json>jsonStr)
}

运行结果:

main.Student{ID:1, Gender:"男", name:"李四", Sno:"s0001"}
{"ID":1,"Gender":"男","Sno":"s0001"}

可以看到由于name是私有属性,因此并不能够被tags" href="/JSON.html" title=json>json包访问,换成Name后就可以了。

  1. Json 字符串转换成结构

代码示例:

package mainimport ("encoding/tags" href="/JSON.html" title=json>json""fmt"
)type Student struct {ID     intGender stringName   stringSno    string
}func main() {var tags" href="/JSON.html" title=json>jsonStr = `{"ID":1,"Gender":"男","Name":"李四","Sno":"s0001"}`var student Studenterr := tags" href="/JSON.html" title=json>json.Unmarshal([]byte(tags" href="/JSON.html" title=json>jsonStr), &student)if err != nil {fmt.Printf("unmarshal err=%v\n", err)}fmt.Printf("反tags" href="/XuLieHua.html" title=序列化>序列化后 student=%#v student.Name=%v \n", student, student.Name)
}

运行结果:

tags" href="/XuLieHua.html" title=序列化>序列化后 student=main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"} student.Name=李四

结构体标签 Tag

Tag 是结构体的元信息,可以在运行的时候通过反射的机制读取出来。 Tag 在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下:

`key1:"value1" key2:"value2"`

结构体 tag 由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。同一个结构体字段可以设置多个键值对 tag,不同的键值对之间使用空格分隔。

注意事项: 为结构体编写 Tag 时,必须严格遵守键值对的规则。结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,通过反射也无法正确取值。例如不要在 key 和 value 之间添加空格。

tags" href="/XuLieHua.html" title=序列化>序列化代码示例:

package mainimport ("encoding/tags" href="/JSON.html" title=json>json""fmt"
)type Student struct {ID     int    `tags" href="/JSON.html" title=json>json:"id"` //通过指定 tag 实现 tags" href="/JSON.html" title=json>json tags" href="/XuLieHua.html" title=序列化>序列化该字段时的 keyGender string `tags" href="/JSON.html" title=json>json:"gender"`Name   stringSno    string
}func main() {var s1 = Student{ID: 1, Gender: "男", Name: "李四", Sno: "s0001"}fmt.Printf("%#v\n", s1)var s, _ = tags" href="/JSON.html" title=json>json.Marshal(s1)tags" href="/JSON.html" title=json>jsonStr := string(s)fmt.Println(tags" href="/JSON.html" title=json>jsonStr)
}

运行结果:

main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}
{"id":1,"gender":"男","Name":"李四","Sno":"s0001"}

tags" href="/XuLieHua.html" title=序列化>序列化代码示例:

package mainimport ("encoding/tags" href="/JSON.html" title=json>json""fmt"
)type Student struct {ID     int    `tags" href="/JSON.html" title=json>json:"id"` //通过指定 tag 实现 tags" href="/JSON.html" title=json>json tags" href="/XuLieHua.html" title=序列化>序列化该字段时的 keyGender string `tags" href="/JSON.html" title=json>json:"gender"`Name   stringSno    string
}func main() {var s2 Studentvar str = "{\"id\":1,\"gender\":\"男\",\"Name\":\"李四\",\"Sno\":\"s0001\"}"err := tags" href="/JSON.html" title=json>json.Unmarshal([]byte(str), &s2)if err != nil {fmt.Println(err)}fmt.Printf("%#v", s2)
}

运行结果:

main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}

从结果可以看出,前两个字段(ID和Gender)后面跟有一个反引号内的特殊标记(tag),这些标记指定了在将结构体tags" href="/XuLieHua.html" title=序列化>序列化为JSON格式时应使用的键名。例如,ID字段对应的JSON键名是"id",而不是默认的驼峰命名"ID"。对于Name和Sno字段,默认会使用字段名称作为JSON中的键名,因为没有特别指定标签。

结构体tag常用的场景

  • 重命名字段
    正如上面案例中所示,结构体中字段为ID,通过tag可以改成id
  • 忽略字段
    可以通过设置标签为tags" href="/JSON.html" title=json>json:"-"来告诉编解码器忽略某个字段。
  • 选项标志
    可以在标签中添加选项标志,比如omitempty,当字段值为空(零值)时,在tags" href="/XuLieHua.html" title=序列化>序列化结果中省略该字段。

嵌套结构体和 JSON tags" href="/XuLieHua.html" title=序列化>序列化反tags" href="/XuLieHua.html" title=序列化>序列化

  1. tags" href="/JSON.html" title=json>jsontags" href="/XuLieHua.html" title=序列化>序列化代码示例
package mainimport ("encoding/tags" href="/JSON.html" title=json>json""fmt"
)// Student 学生
type Student struct {ID     intGender stringName   string
}// Class 班级
type Class struct {Title    stringStudents []Student
}func main() {c := &Class{Title: "001", Students: make([]Student, 0, 200)}for i := 0; i < 10; i++ {stu := Student{Name: fmt.Sprintf("stu%02d", i), Gender: "男", ID: i}c.Students = append(c.Students, stu)}//JSON tags" href="/XuLieHua.html" title=序列化>序列化:结构体-->JSON 格式的字符串data, err := tags" href="/JSON.html" title=json>json.Marshal(c)if err != nil {fmt.Println("tags" href="/JSON.html" title=json>json marshal failed")return}fmt.Printf("tags" href="/JSON.html" title=json>json:%s\n", data)
}

运行结果:

tags" href="/JSON.html" title=json>json:{"Title":"001","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name":"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{"ID":9,"Gender":"男","Name":"stu09"}]}
  1. tags" href="/JSON.html" title=json>json反tags" href="/XuLieHua.html" title=序列化>序列化代码示例
package mainimport ("encoding/tags" href="/JSON.html" title=json>json""fmt"
)// Student 学生
type Student struct {ID     intGender stringName   string
}// Class 班级
type Class struct {Title    stringStudents []Student
}func main() {str := `{"Title":"001","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name":"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{"ID":9,"Gender":"男","Name":"stu09"}]}`c1 := &Class{}err := tags" href="/JSON.html" title=json>json.Unmarshal([]byte(str), c1)if err != nil {fmt.Println("tags" href="/JSON.html" title=json>json unmarshal failed!")return}fmt.Printf("%#v\n", c1)
}

运行结果:

&main.Class{Title:"001", Students:[]main.Student{main.Student{ID:0, Gender:"男", Name:"stu00"}, main.Student{ID:1, Gender:"男", Name:"stu01"}, main.Student{ID:2, Gender:"男", Name:"stu02"}, main.Student{ID:3, Gender:"男", Name:"stu03"}, main.Student{ID:4, Gender:"男", Name:"stu04"}, main.Student{ID:5, Gender:"男", Name:"stu05"}, main.Student{ID:6, Gender:"男", Name:"stu06"}, main.Student{ID:7, Gender:"男", Name:"stu07"}, main.Student{ID:8, Gender:"男", Name:"stu08"}, main.Student{ID:9, Gender:"男", Name:"stu09"}}}

Map、切片的tags" href="/XuLieHua.html" title=序列化>序列化反tags" href="/XuLieHua.html" title=序列化>序列化

Map 和切片也可以进行tags" href="/XuLieHua.html" title=序列化>序列化和反tags" href="/XuLieHua.html" title=序列化>序列化,详情可以参考这篇博客。

参考文献

https://gobyexample.com/

https://www.w3schools.com/go/

https://go.dev/doc/tutorial/

https://www.geeksforgeeks.org/tags" href="/GOLANG.html" title=golang>golang-tutorial-learn-go-programming-language/


http://www.ppmy.cn/embedded/160810.html

相关文章

工业 4G 路由器助力消防领域,守卫生命安全防线

在消防领域也在不断引入新技术以提升消防安全保障能力发展过程中。工业 4G 路由器为其数据传输、预警监控发挥着重要的通信作用。 工业 4G 路由器通过内置的 4G 模块&#xff0c;接入 4G 网络&#xff0c;将网络信号进行转换和分发。它能够适应复杂的工业环境&#xff0c;具备…

A new release of pip is available: 24.2 -> 25.0

您可以使用官方提供的 get-pip.py 脚本来安装或升级pip。 1&#xff0c;下载 get-pip.py 脚本&#xff1a; curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py 2&#xff0c;运行脚本以安装或升级pip&#xff1a; python get-pip.py 3&#xff0c;实际运行效果

Kotlin 2.1.0 入门教程(十)

if 表达式 if 是一个表达式&#xff0c;它会返回一个值。 不存在三元运算符&#xff08;condition ? then : else&#xff09;&#xff0c;因为 if 在这种场景下完全可以胜任。 var max aif (a < b) max bif (a > b) {max a } else {max b }max if (a > b) a…

C# 修改项目类型 应用程序程序改类库

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

C语言练习题

文章目录 1. 递归实现将字符串str中的元素逆序2. 对数组arr进行冒泡排序&#xff08;升序&#xff09;3. 对数组从下标low到下标hihg区间内的元素进行快速排序&#xff08;升序&#xff09;4. 在数组中利用二分查找(折半查找)目标关键字5. 求n的阶乘6. 判断year是否为闰年7. 求…

【再谈设计模式】状态模式~对象行为的状态驱动者

一、引言 在软件开发,软将工程,软件设计过程中,我们常常会遇到对象的行为依赖于其状态的情况。例如,一个任务对象可能有“未开始”、“进行中”、“已完成”等状态,并且在不同状态下执行相同操作会有不同的结果。传统的方法可能会使用大量的条件判断语句来处理不同状态下的…

申论 应用文 【2017副省第四题 “水生态+扶贫”】

材料&#xff1a; 近日&#xff0c;“秋水长天 水美中国”采访团调研了G市的水生态文明建设情况。记者经过走访发现&#xff0c;G市某些区县的“水生态扶贫”模式&#xff0c;对欠发达地区在保持青山绿水的同时大力推进脱贫工作&#xff0c;具有很强的借鉴意义。 G市以山地、…

关于知识蒸馏的概念原理以及常见方法

1. 概念与原理 知识蒸馏的基本定义 知识蒸馏(Knowledge Distillation) 是一种将模型压缩与迁移学习结合的技术:它利用预先训练好的大模型(通常参数量大、精度高、计算开销大)指导一个更轻量(参数量小、推理速度快)的学生模型进行训练,从而在保持模型精度的同时显著减少…