Golang JSON 标准库用法详解

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,Go语言的标准库encoding/json提供了强大的JSON处理能力。下面我将详细介绍各种用法并提供示例代码。

1. 基本编码(Marshal)

将Go数据结构转换为JSON字符串。

package mainimport ("encoding/json""fmt""log"
)type Person struct {Name    string `json:"name"`          // 字段标签指定JSON键名Age     int    `json:"age"`           // 基本类型字段Address string `json:"address"`       // 字符串字段Hobbies []string `json:"hobbies"`     // 切片字段IsAdmin bool   `json:"is_admin"`      // 布尔字段private string // 小写开头字段不会被导出
}func main() {// 创建一个Person实例p := Person{Name:    "Alice",Age:     30,Address: "123 Main St",Hobbies: []string{"reading", "hiking"},IsAdmin: true,private: "secret", // 这个字段不会被编码}// 将结构体编码为JSONjsonData, err := json.Marshal(p)if err != nil {log.Fatal(err)}fmt.Println(string(jsonData))// 输出: {"name":"Alice","age":30,"address":"123 Main St","hobbies":["reading","hiking"],"is_admin":true}
}

2. 美化输出(Indent)

使用MarshalIndent可以生成格式化的JSON输出。

func main() {p := Person{Name:    "Bob",Age:     25,Address: "456 Oak Ave",Hobbies: []string{"gaming", "coding"},}// 使用MarshalIndent美化输出jsonData, err := json.MarshalIndent(p, "", "  ")if err != nil {log.Fatal(err)}fmt.Println(string(jsonData))/*输出:{"name": "Bob","age": 25,"address": "456 Oak Ave","hobbies": ["gaming","coding"],"is_admin": false}*/
}

3. 基本解码(Unmarshal)

将JSON字符串解码为Go数据结构。

func main() {// JSON字符串jsonStr := `{"name": "Charlie","age": 35,"address": "789 Pine Rd","hobbies": ["swimming", "photography"],"is_admin": true}`// 解码JSON到Person结构体var p Personerr := json.Unmarshal([]byte(jsonStr), &p)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", p)// 输出: {Name:Charlie Age:35 Address:789 Pine Rd Hobbies:[swimming photography] IsAdmin:true private:}
}

4. 处理未知结构的JSON

使用map[string]interface{}interface{}处理未知结构的JSON。

func main() {// 复杂的JSON数据jsonStr := `{"name": "Dave","age": 40,"metadata": {"department": "IT","role": "manager","permissions": ["read", "write", "delete"]}}`// 解码到空接口var data interface{}err := json.Unmarshal([]byte(jsonStr), &data)if err != nil {log.Fatal(err)}// 类型断言访问数据m := data.(map[string]interface{})fmt.Println("Name:", m["name"])fmt.Println("Age:", m["age"])// 访问嵌套数据metadata := m["metadata"].(map[string]interface{})fmt.Println("Department:", metadata["department"])fmt.Println("Permissions:", metadata["permissions"])
}

5. 流式处理(Encoder/Decoder)

对于大文件或网络流,可以使用流式处理。

编码器示例(Encoder)

package mainimport ("encoding/json""os"
)func main() {type Book struct {Title  string `json:"title"`Author string `json:"author"`Year   int    `json:"year"`}books := []Book{{"The Go Programming Language", "Alan A. A. Donovan", 2015},{"Effective Go", "The Go Authors", 2009},}// 创建文件file, err := os.Create("books.json")if err != nil {panic(err)}defer file.Close()// 创建JSON编码器encoder := json.NewEncoder(file)// 设置缩进(可选)encoder.SetIndent("", "  ")// 编码数据到文件err = encoder.Encode(books)if err != nil {panic(err)}
}

解码器示例(Decoder)

package mainimport ("encoding/json""fmt""os"
)func main() {// 打开JSON文件file, err := os.Open("books.json")if err != nil {panic(err)}defer file.Close()// 创建JSON解码器decoder := json.NewDecoder(file)var books []struct {Title  string `json:"title"`Author string `json:"author"`}// 解码JSON数据err = decoder.Decode(&books)if err != nil {panic(err)}// 打印结果for _, book := range books {fmt.Printf("%s by %s\n", book.Title, book.Author)}
}

6. 自定义编码/解码

可以通过实现json.Marshalerjson.Unmarshaler接口来自定义编码和解码行为。

package mainimport ("encoding/json""fmt""strings""time"
)// 自定义时间格式
type CustomTime struct {time.Time
}const layout = "2006-01-02"// 实现Marshaler接口
func (ct CustomTime) MarshalJSON() ([]byte, error) {return []byte(`"` + ct.Time.Format(layout) + `"`), nil
}// 实现Unmarshaler接口
func (ct *CustomTime) UnmarshalJSON(data []byte) error {s := strings.Trim(string(data), `"`)t, err := time.Parse(layout, s)if err != nil {return err}ct.Time = treturn nil
}type Event struct {Name      string     `json:"name"`Timestamp CustomTime `json:"timestamp"`
}func main() {// 编码示例event := Event{Name:      "Product Launch",Timestamp: CustomTime{time.Now()},}jsonData, err := json.Marshal(event)if err != nil {panic(err)}fmt.Println(string(jsonData))// 输出: {"name":"Product Launch","timestamp":"2023-04-01"}// 解码示例jsonStr := `{"name":"Team Meeting","timestamp":"2023-04-15"}`var decodedEvent Eventerr = json.Unmarshal([]byte(jsonStr), &decodedEvent)if err != nil {panic(err)}fmt.Printf("%+v\n", decodedEvent)// 输出: {Name:Team Meeting Timestamp:{Time:2023-04-15 00:00:00 +0000 UTC}}
}

7. 处理JSON标签选项

JSON标签可以包含额外的选项来控制编解码行为。

package mainimport ("encoding/json""fmt"
)type User struct {ID        int    `json:"id"`                     // 常规字段Username  string `json:"username"`               // 常规字段Password  string `json:"-"`                      // 忽略字段Email     string `json:"email,omitempty"`        // 如果为空则忽略LastLogin int64  `json:"last_login,omitempty"`   // 如果为零值则忽略IsActive  bool   `json:"is_active,string"`      // 编码为字符串
}func main() {user := User{ID:        1,Username:  "johndoe",Password:  "secret",LastLogin: 0,       // 零值IsActive:  true,}jsonData, err := json.Marshal(user)if err != nil {panic(err)}fmt.Println(string(jsonData))// 输出: {"id":1,"username":"johndoe","is_active":"true"}
}

8. 处理HTML特殊字符

默认情况下,JSON编码器会转义HTML特殊字符。

package mainimport ("encoding/json""fmt"
)func main() {data := map[string]string{"message": "<script>alert('xss')</script>",}jsonData, err := json.Marshal(data)if err != nil {panic(err)}fmt.Println(string(jsonData))// 输出: {"message":"\u003cscript\u003ealert('xss')\u003c/script\u003e"}
}

如果需要禁用HTML转义:

package mainimport ("bytes""encoding/json""fmt"
)func main() {data := map[string]string{"message": "<script>alert('xss')</script>",}buf := new(bytes.Buffer)encoder := json.NewEncoder(buf)encoder.SetEscapeHTML(false) // 禁用HTML转义err := encoder.Encode(data)if err != nil {panic(err)}fmt.Println(buf.String())// 输出: {"message":"<script>alert('xss')</script>"}
}

9. 处理原始JSON消息(RawMessage)

json.RawMessage可以用来延迟解析或传递原始JSON数据。

package mainimport ("encoding/json""fmt"
)type Message struct {Type string          `json:"type"`Data json.RawMessage `json:"data"` // 原始JSON数据
}type TextContent struct {Text string `json:"text"`
}type ImageContent struct {URL  string `json:"url"`Alt  string `json:"alt"`
}func main() {// 模拟接收到的JSON消息jsonStr := `{"type": "image","data": {"url": "https://example.com/image.jpg","alt": "Example image"}}`var msg Messageerr := json.Unmarshal([]byte(jsonStr), &msg)if err != nil {panic(err)}switch msg.Type {case "text":var content TextContenterr = json.Unmarshal(msg.Data, &content)fmt.Println("Text:", content.Text)case "image":var content ImageContenterr = json.Unmarshal(msg.Data, &content)fmt.Println("Image URL:", content.URL, "Alt:", content.Alt)}// 输出: Image URL: https://example.com/image.jpg Alt: Example image
}

10. 处理JSON数组

处理JSON数组数据。

package mainimport ("encoding/json""fmt"
)func main() {// JSON数组字符串jsonStr := `[{"name": "Alice", "age": 25},{"name": "Bob", "age": 30},{"name": "Charlie", "age": 35}]`// 解码到结构体切片var people []struct {Name string `json:"name"`Age  int    `json:"age"`}err := json.Unmarshal([]byte(jsonStr), &people)if err != nil {panic(err)}for _, p := range people {fmt.Printf("%s is %d years old\n", p.Name, p.Age)}/*输出:Alice is 25 years oldBob is 30 years oldCharlie is 35 years old*/
}

总结

Go的encoding/json包提供了强大的JSON处理能力,包括:

  1. 结构体与JSON的相互转换(Marshal/Unmarshal)
  2. 流式处理(Encoder/Decoder)
  3. 自定义编解码行为
  4. 处理复杂和动态JSON结构
  5. 各种标签选项控制编解码行为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/diannao/89114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day.42

hook函数&#xff1a; import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt torch.manual_seed(42) np.random.seed(42) 张量钩子&#xff1a; x torch.tensor([2.0], requires_gradTrue) y x ** 2 z y ** 3 def tensor_hook…

【.net core】【sqlsugar】在where条件查询时使用原生SQL

//初始化查询 var query repository.IQueryable();//添加原生SQL WHERE条件 query query.Where(" fieldA < 123"); 对应调用ISugarQueryable接口类中&#xff1a; ISugarQueryable<T> Where(string whereString, object parameters null);

网络 : 传输层【TCP协议】

网络 : 传输层【TCP协议】 一、TCP协议段格式1.1 32位序号与确认号1.1.1 32位序号1.1.2 确认号 1.2 4位首部长度1.3 6位标志位1.4 16位窗口大小 二、确认应答(ACK)机制三、超时重传机制四、连接管理机制4.1 三次握手(连接)listen的第二个参数 4.2 四次挥手(断开连接)**TIME_WAI…

人大金仓Kingbase数据库 Ksql: 未找到命令

人大金仓Kingbase数据库 Ksql: 未找到命令 1. 定位 Kingbase 安装目录 Kingbase 数据库通常安装在 /kingbase/ES/V8/Server 目录下。可以通过以下命令定位&#xff1a; cd /kingbase/ES/V8/Server2. 验证 ksql 工具是否安装成功 执行以下命令检查 ksql 客户端工具的版本信息…

Flask(四) 模板渲染render_template

文章目录 &#x1f4e6; 过程详解&#xff08;路由 <-> HTML 模板&#xff09;&#x1f9e0; 数据是怎么传过去的&#xff1f;多变量示例 ✅ Jinja2 支持条件判断、循环、模板继承&#xff1a;✅ 安全性&#x1f512; Flask 默认也会对变量进行 HTML 转义&#xff1a;&am…

[附源码+数据库+毕业论文+开题报告]基于Spring+MyBatis+MySQL+Maven+jsp实现的宠物领养管理系统,推荐!

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对宠物领养信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

【ArcGIS】水资源单项评价

【ArcGIS】水资源单项评价 一、水资源单项评价1、评价思路 二、操作步骤1、处理环境设置2、数据处理3、要素转栅格4、水资源评价 一、水资源单项评价 1、评价思路 &#xff08;1&#xff09;省级层面宜选用四级/五级水资源分区或县级行政区为评价单元&#xff0c;按照水资源总…

Windows环境下C语言汇编语言编辑器及环境安装

安装MinGw&#xff1a; 1.下载安装文件 MinGW - 适用于 Windows 的极简主义 GNU 下载 |SourceForge.net 点击下载 下载之后就是如下图的安装文件 2.安装 双击安装文件进行安装&#xff0c;点击Install下一步 选择安装位置&#xff0c;默认是安装在C盘&#xff0c;点击Change…

【数据分析】分段逻辑回归示例分析(模拟数据)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包步骤 1:模拟数据步骤 2:构建逻辑回归和分段模型步骤 3:计算预测值和置信区间步骤 4:提取 OR 和统计值步骤 5:绘图展示结步骤 6:输出图片原始代码总结系统信息参考介绍…

Webpack 构建过程详解

Webpack 是一个功能强大的模块打包工具,它能够将项目中的各种资源(如 JavaScript、CSS、图片等)打包成一个或多个文件,以便于在浏览器中运行。本文将以 Webpack 5 为例介绍它的构建过程: 1. 初始化阶段 在这个阶段,Webpack 从配置文件和命令行参数中读取并解析配置。然…

Flutter基础(UI监听)

文本按钮&#xff08;TextButton&#xff09; 文本按钮是没有边框的按钮&#xff0c;当点击时会有涟漪效果。 TextButton(onPressed: () {// 点击按钮后要执行的代码print(文本按钮被点击了);},child: Text(点击我), ) 手势检测器&#xff08;GestureDetector&#xff09; …

Linux 下的 regulator 子系统

1、简介 regulator 框架是 Linux 内核中用于管理电压和电流调节器&#xff08;如 LDO、DCDC 转换器等&#xff09;的一个子系统。它提供了一个抽象层&#xff0c;使得驱动程序和内核的其他部分可以以一致的方式与调节器进行交互&#xff0c;而无需了解底层硬件的细节。 主要功能…

12345政务热线系统:接诉即办,赋能智慧城市治理

一、12345热线&#xff1a;民情直通车&#xff0c;治理新引擎 “12345”政务热线是党委政府了解社情民意、解决群众合理诉求、倾听批评建议、改进工作作风的重要渠道。当前&#xff0c;全国各城市已基本建成12345政务服务热线体系&#xff0c;形成“接诉即办”的高效响应机制。…

【SpringBoot核心】Spring Boot + MyBatis 深度整合与最佳实践

目录 引言Spring Boot 基础回顾MyBatis 核心概念解析Spring Boot 整合 MyBatisMyBatis 高级特性Spring Boot + MyBatis 最佳实践性能优化与扩展实战案例:电商系统开发常见问题与解决方案总结与展望1. 引言 1.1 技术背景与现状 在现代企业级应用开发中,数据持久化是一个核心…

力扣第77题-组合-力扣第78题-子集

力扣链接:77. 组合 - 力扣&#xff08;LeetCode&#xff09; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3…

嵌入式MTD设备与Flash管理解析

理解MTD是嵌入式系统中处理Flash存储的关键一步&#xff01;我来帮你梳理清楚&#xff1a; MTD 是什么&#xff1f; MTD 是 Memory Technology Device 的缩写&#xff0c;中文常译为内存技术设备。它是 Linux 内核及其衍生系统&#xff08;如嵌入式 Linux&#xff09;中用于管…

基于 GEE 利用 Sentinel-2 数据计算并下载植被指数数据

目录 1 植被指数 2 完整代码 3 运行结果 1 植被指数 植被指数全名NDVI归一化差值植被指数GNDVI绿色归一化差值植被指数EVI增强植被指数EVI2双波段增强植被指数DVI差值植被指数GDVI绿色差植被值指数RVI比值植被指数SAVI土壤调整植被指数OSAVI优化土壤调整植被指数MSAVI修改…

python基础23(2025.6.29)分布式爬虫(增量式爬虫去重)redis应用_(未完成!)

本次写一个爬取网易新闻的案例。因为redis能处理高并发&#xff0c;存储数据也可以&#xff0c;故不用mysql。而且新闻网站容易更新很多&#xff0c;而mysql只能持久化存储。 import scrapy import re import json import redis # 用它来去除重复, 记录访问过的urlclass Wang…

Springboot 集成 SpringState 状态机

Springboot 集成 SpringState 状态机 1.SpringState 简介2.状态机示例2.1 项目结构和依赖包2.2 定义事件类和状态类2.3 Spring 事件监听器2.4 状态机持久化类2.4.1 Redis 状态机持久化容器2.4.2 Redis 配置2.4.3 状态机监听器 2.5 装机器容器2.6 状态机事件发送器2.7 状态机配置…

实战四:基于PyTorch实现猫狗分类的web应用【2/3】

​一、需求描述 实战四分为三部分来实现&#xff0c;第二部分是基于PyTorch的猫狗图像可视化训练的教程&#xff0c;实现了一个完整的猫狗分类模型训练流程&#xff0c;使用预训练的ResNet50模型进行迁移学习&#xff0c;并通过SwanLab进行实验跟踪。 效果图 ​二、实现思路 …