Go 中 JSON 反序列化的结构体标签正确写法

2次阅读

Go 中 JSON 反序列化的结构体标签正确写法

本文详解 go 语言中使用 encoding/json 解析 json结构体字段标签(Struct tags)的规范写法,重点纠正常见错误——遗漏 json 标签中的双引号,导致反序列化失败并返回零值。

go 中,将 json 字符串解码为 Go 结构体是高频操作,但一个看似微小的语法细节却常引发“解析成功但字段为空”的隐蔽问题:JSON struct tag 中的键名必须用英文双引号包裹。若误写为反引号内无引号(如 `json:access_token`),Go 会忽略该标签,转而按字段名(首字母大写的导出名)匹配 JSON 键,而 JSON 中的键是小写的 access_token,无法匹配,最终所有字段保持零值。

以下是一个典型错误示例及其修复:

package main  import (     "encoding/json"     "fmt" )  // ❌ 错误写法:struct tag 中缺少双引号 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 {         fmt.Println("解码错误:", err)         return     }     fmt.Printf("%+vn", apiParams) // 输出:{AccessToken:"" TokenType:"" ExpiresIn:0} }

运行结果为空结构体,正是因为 json:access_token 是非法 tag(缺少双引号),Go 默认使用字段名 AccessToken 去匹配 JSON 中的 “access_token”,显然不匹配。

✅ 正确写法如下——每个 JSON key 必须用双引号包裹在 struct tag 内

type ApiParams struct {     AccessToken string `json:"access_token"` // ✅ 正确:双引号包裹 key     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     if err := json.Unmarshal([]byte(data), &apiParams); err != nil {         panic(err)     }      fmt.Printf("Token: %sn", apiParams.AccessToken)     // 输出:Token: asdfasdf     fmt.Printf("Type: %sn", apiParams.TokenType)         // 输出:Type: bearer     fmt.Printf("Expires in: %d secondsn", apiParams.ExpiresIn) // 输出:Expires in: 5173885 seconds }

? 关键注意事项

  • Struct tag 语法为 `key:”value”`,其中 json 是 key,”access_token” 是 value,双引号不可省略
  • 若 JSON 键与 Go 字段名完全一致(且大小写匹配),可省略 tag(如字段名 AccessToken 对应 JSON “AccessToken”),但实践中绝大多数 API 返回小写下划线命名(snake_case),必须显式指定;
  • 支持额外选项,例如忽略空值:json:”expires_in,omitempty”,或指定字段为必需(需配合自定义解码逻辑);
  • 使用 json.RawMessage 可延迟解析嵌套 JSON,提升灵活性;
  • 始终检查 json.Unmarshal 的返回 Error,避免静默失败。

掌握这一基础但关键的语法规范,能显著减少 JSON 解析类 bug,提升 Go 服务对接外部 API 的健壮性与开发效率。

text=ZqhQzanResources