Go语言JSON结构体标签
· 阅读需 3 分钟
结构体标签详解
type User struct {
ID int `json:"id"` // 字段重命名(服务端返回"id"字段)
Name string `json:"name"` // 保持字段原名
Email string `json:"email,omitempty"` // 空值时自动隐藏(避免空字符串污染JSON)
Secret string `json:"-"` // 彻底隐藏敏感字段(如密码)
Created time.Time `json:"created_at"` // 时间类型自动格式化为RFC3339字符串
}
序列化 最佳实践
// 带缩进的友好格式输出
data, _ := json.MarshalIndent(user, "", " ")
/*
{
"id": 1,
"name": "Alice",
"created_at": "2023-09-15T10:00:00Z"
}
*/
// 原始紧凑格式(适合网络传输)
binaryData, _ := json.Marshal(user) // []byte类型数据
反序列化注意事项
var newUser User
err := json.Unmarshal(data, &newUser)
// 处理日期字段(需显式转换)
type CustomTime struct {
time.Time
}
func (ct *CustomTime) UnmarshalJSON(b []byte) error {
// 自定义日期解析逻辑...
}
常见问题排查
- 字段丢失:检查结构体是否导出(首字母大写)
- 时间格式错误:使用
time.RFC3339
格式字符串 - 零值问题:结合
omitempty
与指针类型*string
- 循环引用:避免结构体嵌套循环
高级技巧
// 动态字段处理
type FlexibleStruct struct {
Extra map[string]interface{} `json:"-"` // 收集未定义字段
}
// 条件序列化
func (u User) MarshalJSON() ([]byte, error) {
// 自定义序列化逻辑...
}
动态类型处理
// 解析未知结构 JSON
data := []byte(`{"name":"Bob","age":30}`)
var result map[string]interface{}
json.Unmarshal(data, &result)
fmt.Println(result["name"].(string))
// 部分解析(使用匿名结构)
var partial struct {
Name string `json:"name"`
}
json.Unmarshal(data, &partial)