
go 的 `encoding/json` 包仅能序列化和反序列化导出(首字母大写)的结构体字段;若字段为小写(未导出),json 解析将静默失败,导致结构体字段为空。
在 Go 中解析 JSON 时,一个常见却容易被忽视的陷阱是:结构体字段必须是导出字段(即首字母大写),否则 json.Unmarshal 或 json.NewDecoder.Decode 将无法为其赋值——即使不报错,字段也始终为空字符串、零值或 nil。
这是因为 Go 的 encoding/json 包基于反射(reflection)工作,而反射只能访问导出(public)字段。未导出字段(如 id string)对包外代码(包括标准库)不可见,因此 JSON 解析器会跳过它们,且不会返回错误。
以下是一个修复后的完整示例:
package main
import (
"encoding/json"
"fmt"
"strings"
)
type RefreshTokenData struct {
Id string `json:"id"`
IssuedAt string `json:"issued_at"` // 推荐使用驼峰命名,更符合 Go 风格
Scope string `json:"scope"`
InstanceURL string `json:"instance_url"`
TokenType string `json:"token_type"`
RefreshToken string `json:"refresh_token"`
IDToken string `json:"id_token"` // 注意:原 JSON 含此字段,原结构体缺失
Signature string `json:"signature"`
AccessToken string `json:"access_token"`
}
func main() {
tokenResp := `{
"id": "https://google.com",
"issued_at": "1423698767063",
"scope": "full refresh_token",
"instance_url": "https://na15.salesforce.com",
"token_type": "Bearer",
"refresh_token": "2os53__CCU5JX_yZXE",
"id_token": "5jSH0Oqm7Q4fc0xkE9NOvW8cA13U",
"signature": "/599EkGVIBsKPFRNkg+58wZ3Q7AFyclvIGvCrxVeyTo=",
"access_token": "sadfasdfasdfasdfdsa"
}`
var tokenData RefreshTokenData
if err := json.Unmarshal([]byte(tokenResp), &tokenData); err != nil {
fmt.Printf("❌ JSON 解析失败: %v\n", err)
return
}
fmt.Printf("✅ 成功解析:\n")
fmt.Printf("- RefreshToken: %q\n", tokenData.RefreshToken)
fmt.Printf("- AccessToken: %q\n", tokenData.AccessToken)
fmt.Printf("- IDToken: %q\n", tokenData.IDToken)
}✅ 输出示例:✅ 成功解析:- RefreshToken: "2os53__CCU5JX_yZXE"- AccessToken: "sadfasdfasdfasdfdsa"- IDToken: "5jSH0Oqm7Q4fc0xkE9NOvW8cA13U"
关键注意事项:
- 字段必须导出:所有需参与 JSON 编解码的字段名首字母必须大写(如 RefreshToken 而非 refresh_token);
- Tag 映射仍有效:json:"refresh_token" 标签仅控制 JSON 键名映射,不影响导出性;
- 字段完整性很重要:原始 JSON 中存在 "id_token" 字段,但初始结构体未定义,会导致该字段丢失;建议对照 JSON 响应完整定义结构体,或使用 map[string]interface{} + 类型断言做动态解析;
- 推荐命名风格:Go 社区惯例使用 CamelCase(如 IssuedAt, InstanceURL)而非下划线,既保持导出性,又提升可读性;
- 错误处理不可省略:虽然本例中解析成功,但生产环境务必检查 err,避免静默失败掩盖逻辑问题。
遵循以上原则,即可确保 Go 中 JSON 解析稳定、可靠、可维护。










