jsonv2为字段设置自定义格式
来源:17golang原创
时间:2026-11-15 03:08:22 491浏览 收藏
在 Go 1.25 的 JSON v2 实验接口中,可在结构体的 json 标签中加入 format:值,为支持该格式的字段指定表示方式。例如时间字段使用 format:'2006-01-02' 表达日期字符串。格式由字段类型解释,不能把任意格式名套到任意类型上。
官方地址:https://pkg.go.dev/encoding/json/v2@go1.25.0
本文示例明确针对 Go 1.25 实验接口。它不受 Go 1 兼容性承诺保护;最新包文档的标签列表已经与这个版本不同。维护其他版本项目时,应打开对应版本文档,不能只复制旧实验标签。这里的 jsonv2 是示例导入别名,实际路径为 encoding/json/v2。
固定工具链,让输入与格式约定一致
假设要保存一份日报:业务层提供一个日期,JSON 文件只需要年、月、日。先决定传输数据的含义,再决定字段表示。日期不携带完整时刻信息,如果业务需要精确到秒的事件时间,就不应为了页面好看而在存储时删掉时分秒。
Go 1.25 的该实验包需要构建时设置 GOEXPERIMENT=jsonv2。请使用已经安装的 Go 1.25 工具链;下面命令本身不会把其他版本自动切换为 Go 1.25。
# 在 Go 1.25 工具链中为当前命令启用 JSON v2 实验。 GOEXPERIMENT=jsonv2 go run main.go
把项目的工具链版本和实验变量写入开发说明,团队成员与构建环境使用同一约定。不要因为标签能够写进源码,就推断当前实际调用的编码器一定理解它。
把格式绑定到传输字段
本例的 Report 只有 Name 与 Day 两个字段。Day 在 Go 内部仍是 time.Time;标签约束的是其 JSON 表示。JSON 字段名 day 与日期布局分别承担命名和格式职责,不要混写。
package main
import (
jsonv2 "encoding/json/v2"
"fmt"
"log"
"time"
)
// Report 是传输对象;日期格式只属于这个字段的 JSON 表示。
type Report struct {
Name string `json:"name"`
Day time.Time `json:"day,format:'2006-01-02'"`
}
func main() {
// 使用零时分秒的 UTC 日期,避免把日期字段误当作完整时间戳。
source := Report{
Name: "inventory",
Day: time.Date(2026, 11, 15, 0, 0, 0, 0, time.UTC),
}
data, err := jsonv2.Marshal(source)
if err != nil {
log.Fatal(err) // 编码失败时不保存不完整结果。
}
fmt.Println(string(data))
// 用相同传输结构读取,不能随意换成默认时间格式字段。
var restored Report
if err := jsonv2.Unmarshal(data, &restored); err != nil {
log.Fatal(err)
}
fmt.Println(restored.Day.Format("2006-01-02"))
}
按上述输入与格式约定,JSON 中的 day 应表达字符串“2026-11-15”,最后一行打印同一日期。这是示例的预期含义,不是本文的运行记录。读者可以在自己的 Go 1.25 环境中观察编码结果与返回错误。

保存表示时,也保留读取约定
将 JSON 保存到文件或交给接口消费者后,日期布局就成为双方约定的一部分。读取端应使用对应的字段模型和版本。示例里用同一个 Report 解码,目的是把往返转换的配置放在同一处,降低两端各写一份规则的维护成本。
业务内部可以保留更完整的数据对象,在输出前转换为传输对象。这样同一份数据用于日志、页面和交换文件时,能够分别选择需要的表示。若原始值包含业务时区与时间,请明确日期按哪个时区计算,再构造日期传输字段;仅保存日期无法还原原始完整时刻。
| 层面 | 本例对象 | 维护重点 |
|---|---|---|
| 业务含义 | 日报所属日期 | 先确定日期如何划分 |
| Go 传输模型 | Report.Day | 字段类型与布局配套 |
| 交换表示 | JSON 的 day 字符串 | 消费者知道它是日期 |
| 读取模型 | restored Report | 与写入约定对应 |

遇到错误时,先缩小到一个字段
如果格式设置未达到预期,先确认工具链版本、实验开关和导入路径,再把结构体缩小为单个时间字段。不要同时修改字段类型、格式和输入值,否则很难知道是哪一处改变了表现。
所有编码与解码调用都应处理返回错误。编码失败后不要把返回内容直接作为成功文件保存;解码失败后,也不要把目标结构中的部分数据直接提交给业务处理。错误文案可能随实验版本变化,业务逻辑不宜依赖整段错误字符串。
需要迁移历史文件时,先区分旧文件使用的日期约定,再确定读取模型。不要通过覆盖旧文件来“试格式”;可写出新文件并保留原数据,待消费端完成迁移后再按项目保留策略清理。这里不要求为每种格式增加全局自定义编码方法:先解决当前字段的表示,再判断是否确实需要更复杂的类型级扩展。
常见问题
format 能用来控制缩进吗?本例讨论字段值的语义表示。缩进与换行属于 JSON 文本的排版问题,不能用日期布局代替。
可以写成 yyyy-MM-dd 吗?本例使用 Go 时间布局的参考日期写法“2006-01-02”。不要把其他语言的日期占位符直接搬进来。
这个标签会改变 time.Time 本身吗?不会把字段类型改成字符串。它描述该版本编码器如何表示字段;领域数据与传输数据仍需分别设计。
为什么不直接推荐所有项目切换?这是限定版本的实验接口示例。已有项目应按工具链与接口兼容需求决定,不应把某个旧实验标签当成稳定迁移承诺。
-
860 收藏
-
843 收藏
-
826 收藏
-
809 收藏
-
792 收藏
-
455 收藏
-
367 收藏
-
224 收藏
-
114 收藏
-
225 收藏
-
253 收藏
-
332 收藏
-
439 收藏
-
Golang · Go教程 | 30分钟前 | 标准库 · 连接池 · Go教程 · 性能排查 · HTTP客户端 · Go net/http 连接复用 keep-alive http.Transport http.Client HTTP/1384 收藏
-
Golang · Go教程 | 33分钟前 | JSON · Go教程 · 版本迁移 · 兼容性 · Go encoding/json encoding/json/v2 JSON迁移 DefaultOptionsV1162 收藏
-
246 收藏
-
224 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习