Go语言JSON序列化与反序列化实战指南

Felix
Felix
发布时间:2026-10-15 | 3人浏览过
原创

掌握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 会按顺序检查以下接口:

  1. json.Marshaler:如果实现了 MarshalJSON() ([]byte, error),则直接返回该方法的输出。
    注意:返回值需符合标准JSON字符串格式(即两端带双引号)。
  2. 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序列化工具使用及网络编程的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表