Go语言JSON序列化与反序列化实战指南
掌握Go语言的序列化与反序列化是处理API数据和配置文件的必备技能。本文将通过具体代码示例,演示如何使用内置的 encoding/json 包对结构体、切片和映射进行JSON转换,并深入解析如何通过自定义接口实现灵活的序列化策略。
序列化核心操作
在Go语言中,序列化是将内存中的数据结构转换为JSON字节流的过程。标准库 encoding/json 提供了主要的方法 Marshal 和 MarshalIndent。
第1步:基础数据序列化
对于常见的结构体、数组和Map,直接使用 json.MarshalIndent 可以获得带有缩进格式的易读JSON字符串。
- 入口:
encoding/json包 - 动作:调用
MarshalIndent(v interface{}, prefix string, indent string) - 参数说明:
v为待序列化对象;prefix为每行开头的前缀(通常留空);indent为缩进字符(如空格或Tab)。
// 定义结构体
type Student struct {
Id int64
Name string
Desc string
}
func demoSerialize() {
// 1. Struct序列化
std := &Student{0, "Ruoshui", "this to Go"}
data, err := json.MarshalIndent(std, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(data))
// 2. Slice序列化
s := []string{"Go", "java", "php"}
d, _ := json.MarshalIndent(s, "", "\t")
fmt.Println(string(d))
// 3. Map序列化
m := map[string]string{
"id": "0",
"name": "ruoshui",
"des": "this to Go",
}
bytes, _ := json.Marshal(m)
fmt.Println(string(bytes))
}
第2步:自定义序列化逻辑
当默认序列化行为不符合需求时(例如需要排除某些字段或改变字段名),可以自定义类型实现特定接口。Go的 json.Marshal 会按顺序检查以下接口:
json.Marshaler:如果实现了MarshalJSON() ([]byte, error),则直接返回该方法的输出。
注意:返回值需符合标准JSON字符串格式(即两端带双引号)。encoding.TextMarshaler:若未实现上述接口,且实现了MarshalText() (text []byte, err error),则调用此方法。
注意:返回值是不带额外引号的纯文本内容。
// 接口定义示例
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
// 若需自定义输出内容,可实现此接口
type TextMarshaler interface {
MarshalText() (text []byte, err error)
}
反序列化核心操作
反序列化是将JSON字节流还原为Go数据类型的过程。关键方法是 json.Unmarshal。
第3步:解析JSON到目标结构
Unmarshal 函数接收JSON字节数据和目标对象的指针。由于Go语言需要通过指针修改外部变量的值,因此第二个参数必须是地址(引用类型或结构体指针)。
- 入口:
encoding/json包 - 动作:调用
Unmarshal(data []byte, v interface{}) error - 重要参数:
v必须是指针,用于接收解析后的数据。
// Struct反序列化示例
type Student struct {
Id int64 `json:"id,string"`
Name string `json:"name,omitempty"`
Desc string `json:"desc"`
}
func demoDeserialize() {
str := `{"id":"0", "name":"ruoshui", "desc":"new Std"}`
var st Student
// 注意:st 必须传入地址 &st
err := json.Unmarshal([]byte(str), &st)
if err != nil {
panic(err)
}
fmt.Println(st)
// Slice反序列化
sliceStr := `["java", "php", "go"]`
var sli []string
json.Unmarshal([]byte(sliceStr), &sli)
fmt.Println(sli)
// Map反序列化
mapStr := `{"a":"java", "b":"node", "c":"php"}`
var newMap map[string]string
json.Unmarshal([]byte(mapStr), &newMap)
fmt.Println(newMap)
}
结构体Tag的使用
在进行序列化和反序列化时,结构体字段上的JSON Tag起着决定性作用。以上述代码为例:
`json:"id,string"`:将整型Id序列化为JSON字符串类型的数字(如"0"而非0)。`json:"name,omitempty"`:当Name字段为空时,在序列化结果中省略该字段。`json:"desc"`:指定JSON中的键名为desc。
总结
通过掌握 Marshal 和 Unmarshal 的基本用法,结合结构体Tag和自定义接口,可以灵活应对绝大多数JSON数据处理场景。在实际开发中,务必注意反序列化时传递指针参数,并处理好错误情况。
以上就是Go语言中JSON序列化与反序列化的详细内容,更多关于Go序列化工具使用及网络编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









