商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何在 Go 中正确将结构体切片序列化为 JSON

如何在 Go 中正确将结构体切片序列化为 JSON

  发布于2026-07-10 阅读(0)

扫一扫,手机访问

go 的 json 包只能序列化导出(首字母大写)的结构体字段;若 calendarday 中的字段为小写(如 day、weekday),则会被忽略,导致 json 输出为空对象 {}。

在 Go 日常开发中,JSON 序列化是个高频操作,但很多人初学时都会踩到一个坑:明明结构体切片里有数据,序列化出来却只有一对空大括号 —— {}。这种问题其实很典型,根源就在于 Go 的 JSON 序列化机制有一个硬性规则。

Go 标准库的 encoding/json 包在序列化时,依赖的是反射机制。而这个机制的限制非常直接:反射只能访问导出的字段。所谓导出字段,就是那些以大写字母开头的字段名。换句话说,如果你结构体里写的是 dayweekday,它们都是小写首字母,属于未导出字段。那么不管是 json.Marshal 还是 json.NewEncoder.Encode,都会直接跳过它们。即使你的切片非空,最终输出的也只能是一个空对象。

所以,正确的做法其实很简单:把字段名改为大写开头,同时通过 JSON 标签(tag)控制序列化后的键名。就像下面这样:

type CalendarDay struct {  
    Day     int    `json:"day"`      // 导出字段:Day → 对应 JSON key "day"  
    Weekday string `json:"weekday"` // 导出字段:Weekday → 对应 JSON key "weekday"  
}

另外,别忘了确认外层结构体 CalendarYear 中的字段也是导出的。从你给出的定义来看,JanuaryFebruary 等字段名都是大写开头,这部分本身是正确的。

这里有几个值得注意的细节:

  • 导出性由字段名的首字母决定,JSON 标签(如 json:"day")只控制序列化后的键名,并不会改变字段的可见性。很多新手会误以为加了标签就能解决,其实不然。
  • 如果某些字段在值为零值时不需要出现在 JSON 中,可以加上 ,omitempty。比如 json:"day,omitempty",这样当 Day 为 0 时,该字段会被忽略。
  • 开发调试时,可以用 json.MarshalIndent 来获得格式化的输出,一眼就能看清数据结构:
data, _ := json.MarshalIndent(year, "", "  ")  
fmt.Println(string(data))

完整修复之后,调用 getYear(2015) 再编码,你就能得到想要的 JSON 结构了:

{  
  "january": [  
    {"day": 1, "weekday": "Thursday"},  
    {"day": 2, "weekday": "Friday"},  
    ...  
  ],  
  "february": [...],  
  ...  
}

说到底,Go 的序列化安全模型并不是在为难你。它强制要求显式导出字段,本质上是一种封装性与 API 明确性的设计选择。遇到 JSON 输出空对象的问题时,第一反应就去检查结构体字段是否首字母大写——这条经验,能解决 90% 的相似问题。

本文转载于:https://www.php.cn/faq/2393139.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注