Golang中JSON序列化和反序列化详解
在Golang开发中,数据交换常依赖JSON格式。本文将演示如何利用encoding/json包中的Marshal和Unmarshal函数,对基础类型、结构体、Map及切片进行高效转换,涵盖字段重命名等关键特性。
JSON简介与核心机制
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,基于ECMAScript规范。因其结构清晰、易于阅读和机器解析,被广泛用于网络传输。在Golang程序中,通常将内存对象序列化为JSON字符串发送,接收方再将其反序列化还原为原始数据结构。
基本数据类型序列化
Golang内置了强大的工具函数来处理各类数据类型。首先来看最基础的数据类型序列化。使用json.Marshal可以将Go的基本变量转换为JSON字节流。
func testBasic() {
num := 1.111
// 执行序列化
marshal, err := json.Marshal(num)
if err != nil {
fmt.Println("json.Marshal err:", err)
}
fmt.Println("序列化后:", string(marshal)) // 输出: 1.111
}
结构体序列化与JSON Tag
在实际业务中,最常使用的是结构体序列化。Golang默认导出结构体字段(首字母大写),但在生成JSON时可能需要自定义键名。此时需利用结构体标签(Struct Tag)来实现。
以下示例展示了如何定义带有JSON标签的结构体。通过在字段后添加`json:"key_name"`,可以指定序列化后的JSON字段名:
type Student struct {
Name string `json:"student_name"`
Age int `json:"student_age"`
Birthday string `json:"student_birthday"`
Address string `json:"student_address"`
}
func testStudent() {
student := Student{
Name: "itzhuzhu",
Age: 24,
Birthday: "1998-01-01",
Address: "广州市天河区",
}
// 注意传入指针或值均可,此处传入地址
marshal, err := json.Marshal(&student)
if err != nil {
fmt.Println("json.Marshal err:", err)
}
fmt.Println("序列化结果:", string(marshal))
}
注意:未设置标签的字段将保持原名作为JSON Key;若字段首字母小写(私有字段),则无法被序列化。
Map与切片序列化
除了结构体,动态性强的Map和切片同样支持JSON序列化,适用于Schema不确定的场景。
Map序列化
func testMap() {
m := make(map[string]interface{})
m["name"] = "韩信"
m["age"] = 23
m["address"] = "广州"
marshal, err := json.Marshal(m)
if err != nil {
fmt.Println("json.Marshal err:", err)
}
fmt.Println("序列化后:", string(marshal))
}
切片序列化
当处理列表数据时,可创建元素类型为interface{}或具体类型的切片:
func testSlice() {
var slice []map[string]interface{}
m := make(map[string]interface{})
m["name"] = "韩信"
m["age"] = 23
m["address"] = "广州"
slice = append(slice, m)
marshal, err := json.Marshal(slice) // 修复:应序列化slice而非m
if err != nil {
fmt.Println("json.Marshal err:", err)
}
fmt.Println("序列化后:", string(marshal))
}
JSON反序列化操作
反序列化使用json.Unmarshal方法,将JSON字节流还原为Go数据结构。目标变量的类型必须与JSON内容兼容。
反序列化为结构体
将JSON字符串转为结构体时,需确保字段匹配:
func deserialize() {
str := "{\"Name\":\"itzhuzhu\",\"Age\":24,\"Birthday\":\"1998-01-01\",\"Address\":\"广州市天河区\"}"
var student Student
// Unmarshal会将JSON字段映射到对应的结构体字段
err := json.Unmarshal([]byte(str), &student)
if err != nil {
fmt.Println("json.Unmarshal err:", err)
}
fmt.Println("反序列化后:", student)
}
反序列化为Map和切片
对于Map,无需预先调用make初始化,因为Unmarshal会自动分配内存:
func deserializeMap() {
str := " {\"address\":\"广州\",\"age\":23,\"name\":\"韩信\"}"
var m map[string]interface{}
err := json.Unmarshal([]byte(str), &m)
if err != nil {
fmt.Println("json.Unmarshal err:", err)
}
fmt.Println("反序列化后:", m)
}
func deserializeSlice() {
str := " [{\"address\":\"广州\",\"age\":23,\"name\":\"韩信\"}]"
var slice []map[string]interface{}
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Println("json.Unmarshal err:", err)
}
fmt.Println("反序列化后:", slice)
}
以上就是Golang中JSON序列化和反序列化的详细内容,更多关于Golang数据处理技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









