互联网协议必备:Go语言中JSON的序列化与反序列化

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 互联网协议必备:Go语言中JSON的序列化与反序列化

/ Go 语言将结构体序列化和存储为 JSON 数据指南 /


 

一、概述

JSON 是一种非常流行的数据交换格式,在 Go 语言中经常需要将结构体实例序列化为 JSON 字符串保存和传输。本文将详细介绍如何使用 Go 语言中的 encoding/json 包将结构体序列化为 JSON 数据。

主要内容包括:

  • JSON 序列化概述
  • 定义可序列化的结构体
  • 使用 json.Marshal 序列化
  • 定制序列化逻辑
  • 使用 json.Unmarshal 反序列化
  • 处理空值和默认值
  • 嵌套对象和匿名字段
  • 序列化 interface{}
  • stream 编码器
  • JSON 与 XML 对比
  • 文本格式的优点
  • 使用规范
  • 序列化性能优化

通过本文可以全面了解 Go 语言中处理 JSON 的知识,及如何使用 json 包将结构体快速序列化为 JSON。


 

二、JSON 序列化概述

JSON 是一种非常流行的结构化数据格式,被广泛用于各种网络传输和数据存储之中。

Go 语言中主要通过 json 包来处理 JSON 数据,其中两个核心函数:

  • json.Marshal 序列化 Go 对象为 JSON 格式字节流
  • json.Unmarshal JSON 数据解析为 Go 对象

十分方便地实现序列化与反序列化。


 

三、定义可序列化的结构体

要将一个结构体实例序列化为 JSON,需要确保结构体字段可被 json 包访问,通常有两种方式:

  1. 字段首字母大写,则可以被外部包访问

  2. 通过 tag 指定 json 字段名

一个例子:

type User struct {
  ID int `json:"id"`
  Name string `json:"name"` 
  Age int
}


这样 User 结构体可以正确序列化和反序列化。


 

四、使用 json.Marshal 序列化

将对象编码为 JSON 字节流十分简单:

package main
import (
  "encoding/json"
  "fmt"
)
type User struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}
func main() {
  user := User{"John", 20}
  // 序列化
  buf, err := json.Marshal(user)
  if err != nil {
    fmt.Println(err)
    return
  }
  // 打印JSON
  fmt.Println(string(buf))
}


运行结果:

{"name":"John","age":20}

通过 json.Marshal 即可将结构体序列化。


 

五、定制序列化逻辑

如果需要控制序列化的细节,可以实现 Marshaler 接口:

package main
import (
  "encoding/json"
  "fmt"
)
type User struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}
// 实现Marshaler接口
func (u User) MarshalJSON() ([]byte, error) {
  return []byte(fmt.Sprintf(`{"name":"%s"}`, u.Name)), nil
}
func main() {
  u := User{"John", 20}
  jsonBytes, _ := json.Marshal(u)
  fmt.Println(string(jsonBytes)) // {"name":"John"}
}


这样我们可以灵活控制各字段的编码过程。


 

六、使用 json.Unmarshal 反序列化

对于反序列化 JSON 解析为 Go 对象,可以简单的调用 json.Unmarshal:

package main
import (
  "encoding/json"
  "fmt"
)
type User struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}
func main() {
  jsonStr := `{"name":"John","age":20}`
  // 反序列化到user
  var user User
  err := json.Unmarshal([]byte(jsonStr), &user)
  if err != nil {
    fmt.Println(err)
    return 
  }
  fmt.Println(user.Name) // John
  fmt.Println(user.Age) // 20 
}

传入 JSON 数据以及对象指针,即可解析为对应对象。


 

七、处理空值和默认值

对于空值的序列化,默认会忽略空值字段:

type User struct {
  Name string
  Age  int
}
u := User{"John", 0} 
jsonBytes, _ := json.Marshal(u)
fmt.Println(string(jsonBytes)) // {"Name":"John"}

但可以通过定义 MarshalJSON 方法自定义处理空值的编码。

反序列化时,需要处理不存在的字段,可以使用指针或默认值。


 

八、嵌套对象和匿名字段

对于嵌套的对象字段和内嵌匿名类型,也可以正常序列化和反序列化:

type Info struct {
  Addr string
}
type User struct {
  Info // 嵌套Info
  Name string
}
u := User{Info{"Beijing"}, "Tom"}
jsonBytes, _ := json.Marshal(u)
fmt.Println(string(jsonBytes)) // {"Addr":"Beijing","Name":"Tom"}

编码后嵌套的类型将被内联到结果中。


 

九、序列化 interface{}

json 包可以处理任意的 interface{}值:

data := map[string]interface{}{
  "name": "John",
  "age": 20,
}
jsonBytes, _ := json.Marshal(data)
fmt.Println(string(jsonBytes))

但编码结果会包含类型信息和 Base64 编码后的值。这比定制序列化更低效。


 

十、stream 编码器

我们也可以使用 streaming 模式的 encoder 来进行序列化:


package main
import (
  "encoding/json"
  "os"
)
func main() {
  type User struct {
    Name string
    Age  int
  }
  user := User{"John", 20}
  // 使用stream encoder
  enc := json.NewEncoder(os.Stdout)
  enc.Encode(user)
}

这种编码方式非常灵活,可实现各种自定义输出格式。


 

十一、JSON 与 XML 对比

相比 XML,JSON 具有以下优点:

  • 读取和解析更加方便快捷
  • 存储占用更小且具有可读性
  • 支持更多语言与平台
  • 性能和解析速度更快

这使得 JSON 成为主流的数据交换格式。


 

十二、文本格式的优点

JSON 与其他二进制序列化格式相比,文本格式 JSON 有以下优势:

  • 可读性强,便于打印调试
  • 可复用现有文本处理工具
  • 不依赖语言和平台
  • 可支持部分更新修改

这些特点使 JSON 很适合作为配置、通信和数据存储格式。


 

十三、使用规范

使用 JSON 时,也应注意遵守一定规范:

  • 格式化打印 JSON 数据
  • 为类型和字段定义 Canonical 名称
  • 提供完整的文档
  • 版本控制 JSON 接口
  • 采用更灵活的 schema 描述

这可以确保使用 JSON 的稳定性和兼容性。


 

十四、序列化性能优化

对于性能敏感的场景,可以通过以下技巧优化序列化:

  • 提前指定好对象大小
  • 重用分配的内存
  • 尽量避免解析嵌套数据
  • 按需完成自定义编码

针对特定用例微优化这些方面可以提升 JSON 处理的性能。


 

十五、总结

JSON 作为平台无关的数据交换格式,在 Go 语言中有着广泛的应用。本文详细介绍了 Go 语言序列化结构体为 JSON 的知识,希望大家可以运用自如。

管理和转换 JSON 是后端开发中经常进行的工作,这些知识也可以应用到许多其他语言中。掌握好这些技能,可以大大提高我们的开发效率。



目录
相关文章
|
4天前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
51 20
|
2天前
|
存储 监控 算法
探秘员工泄密行为防线:基于Go语言的布隆过滤器算法解析
在信息爆炸时代,员工泄密行为对企业构成重大威胁。本文聚焦布隆过滤器(Bloom Filter)这一高效数据结构,结合Go语言实现算法,帮助企业识别和预防泄密风险。通过构建正常操作“指纹库”,实时监测员工操作,快速筛查可疑行为。示例代码展示了如何利用布隆过滤器检测异常操作,并提出优化建议,如调整参数、结合日志分析系统等,全方位筑牢企业信息安全防线,守护核心竞争力。
|
10天前
|
Go C语言
Go语言入门:分支结构
本文介绍了Go语言中的条件语句,包括`if...else`、`if...else if`和`switch`结构,并通过多个练习详细解释了它们的用法。`if...else`用于简单的条件判断;`if...else if`处理多条件分支;`switch`则适用于基于不同值的选择逻辑。特别地,文章还介绍了`fallthrough`关键字,用于优化重复代码。通过实例如判断年龄、奇偶数、公交乘车及成绩等级等,帮助读者更好地理解和应用这些结构。
34 14
|
24天前
|
存储 监控 算法
内网监控系统之 Go 语言布隆过滤器算法深度剖析
在数字化时代,内网监控系统对企业和组织的信息安全至关重要。布隆过滤器(Bloom Filter)作为一种高效的数据结构,能够快速判断元素是否存在于集合中,适用于内网监控中的恶意IP和违规域名筛选。本文介绍其原理、优势及Go语言实现,提升系统性能与响应速度,保障信息安全。
28 5
|
1月前
|
算法 安全 Go
Go语言中的加密和解密是如何实现的?
Go语言通过标准库中的`crypto`包提供丰富的加密和解密功能,包括对称加密(如AES)、非对称加密(如RSA、ECDSA)及散列函数(如SHA256)。`encoding/base64`包则用于Base64编码与解码。开发者可根据需求选择合适的算法和密钥,使用这些包进行加密操作。示例代码展示了如何使用`crypto/aes`包实现对称加密。加密和解密操作涉及敏感数据处理,需格外注意安全性。
46 14
|
1月前
|
Go 数据库
Go语言中的包(package)是如何组织的?
在Go语言中,包是代码组织和管理的基本单元,用于集合相关函数、类型和变量,便于复用和维护。包通过目录结构、文件命名、初始化函数(`init`)及导出规则来管理命名空间和依赖关系。合理的包组织能提高代码的可读性、可维护性和可复用性,减少耦合度。例如,`stringutils`包提供字符串处理函数,主程序导入使用这些函数,使代码结构清晰易懂。
95 11
|
1月前
|
存储 安全 Go
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
|
9天前
|
监控 关系型数据库 MySQL
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
19 0
|
1月前
|
监控 安全 算法
深度剖析核心科技:Go 语言赋能局域网管理监控软件进阶之旅
在局域网管理监控中,跳表作为一种高效的数据结构,能显著提升流量索引和查询效率。基于Go语言的跳表实现,通过随机化索引层生成、插入和搜索功能,在高并发场景下展现卓越性能。跳表将查询时间复杂度优化至O(log n),助力实时监控异常流量,保障网络安全与稳定。示例代码展示了其在实际应用中的精妙之处。
44 9
|
2月前
|
算法 安全 Go
Go 语言中实现 RSA 加解密、签名验证算法
随着互联网的发展,安全需求日益增长。非对称加密算法RSA成为密码学中的重要代表。本文介绍如何使用Go语言和[forgoer/openssl](https://github.com/forgoer/openssl)库简化RSA加解密操作,包括秘钥生成、加解密及签名验证。该库还支持AES、DES等常用算法,安装简便,代码示例清晰易懂。
64 12

热门文章

最新文章