
本文详解 go 语言中使用 `encoding/json` 包解码 json 时结构体字段标签的规范写法,重点纠正因缺少双引号导致的反序列化失败问题,并提供可运行示例与最佳实践。
在 Go 中解析 JSON 数据是高频操作,但初学者常因一个细微疏忽导致反序列化失败——结构体字段的 JSON 标签(struct tag)中遗漏了必需的双引号。例如,以下代码看似合理,实则无法正确解码:
type ApiParams struct {
AccessToken string `json:access_token` // ❌ 错误:缺少双引号
TokenType string `json:token_type`
ExpiresIn int64 `json:expires_in`
}该写法会使 json.Unmarshal 完全忽略字段映射,最终得到零值结构体(如空字符串、0 值整数),而不会报错——这是典型的“静默失败”,极难排查。
✅ 正确写法必须为每个 json 标签的键和值都加上英文双引号:
type ApiParams struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int64 `json:"expires_in"`
}完整可运行示例:
package main
import (
"encoding/json"
"fmt"
)
type ApiParams struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int64 `json:"expires_in"`
}
func main() {
data := `{
"access_token": "asdfasdf",
"token_type": "bearer",
"expires_in": 5173885
}`
var apiParams ApiParams
err := json.Unmarshal([]byte(data), &apiParams)
if err != nil {
panic(err) // 或适当错误处理
}
fmt.Printf("Token: %s\n", apiParams.AccessToken) // 输出: Token: asdfasdf
fmt.Printf("Type: %s\n", apiParams.TokenType) // 输出: Type: bearer
fmt.Printf("Expires in: %d seconds\n", apiParams.ExpiresIn) // 输出: Expires in: 5173885 seconds
}? 关键注意事项:
- 双引号不可省略:json:"key" 是合法标签;json:key 或 json:access_token 均无效,Go 会将其视为无意义的字面量,跳过字段映射。
- 支持别名与选项:可在双引号内添加逗号分隔的选项,如 json:"expires_in,omitempty"(空值不序列化)、json:"access_token,string"(将字符串转为数字等类型转换,需配合自定义方法)。
- 大小写敏感:JSON 键名严格区分大小写,结构体字段名可任意(如 AccessToken 映射 "access_token"),但标签值必须与 JSON 中的实际 key 完全一致。
- 嵌套与切片同样适用:复杂结构(如嵌套对象、数组)只需为对应字段正确声明带双引号的 json 标签即可,json.Unmarshal 会自动递归解析。
总结:Go 的 JSON 解析高度依赖结构体标签的语法准确性。牢记 json:"field_name" 是唯一标准格式——少一对双引号,就少一次成功解码。养成编写结构体时立即补全引号的习惯,可显著提升开发效率与程序健壮性。










