golang,go,博客,开源,编程
Go语言的 encoding/json
是标准库中用于处理 JSON 数据的核心模块,支持高效序列化(Marshal)与反序列化(Unmarshal)操作。以下从核心功能、使用技巧、性能优化及场景实践四个维度展开详细说明。
数据绑定原理通过结构体标签(Tag)实现 JSON 键与 Go 结构体字段的映射:
type User struct {
Name string `json:"name"` // 字段重命名
Age int `json:"age,omitempty"` // 空值忽略
Roles []Role `json:"roles"` // 嵌套结构
}
标签语法支持 omitempty
(零值忽略)、string
(数字转字符串)等扩展参数。
序列化与反序列化
• Marshal:结构体 → JSON
user := User{Name: "Alice", Age: 25}
jsonData, _ := json.Marshal(user)
// 输出:{"name":"Alice","age":25}
• Unmarshal:JSON → 结构体
jsonStr := `{"name":"Bob","age":30}`
var user User
json.Unmarshal([]byte(jsonStr), &user)
支持 json.RawMessage
处理未解析原始数据。
**流式处理(Streaming)**针对大文件或网络流,使用 Decoder
/Encoder
减少内存占用:
// HTTP 请求体解析
func HandleRequest(w http.ResponseWriter, r *http.Request) {
var user User
json.NewDecoder(r.Body).Decode(&user)
// ...
}
// 响应生成
json.NewEncoder(w).Encode(user)
此方式比 Marshal
节省 40% 内存。
动态 JSON 处理使用 map[string]interface{}
或空接口处理未知结构:
var data map[string]interface{}
json.Unmarshal(jsonData, &data)
if value, exists := data["key"]; exists {
// 类型断言处理
}
自定义序列化
通过实现 Marshaler
/Unmarshaler
接口定制逻辑:
type CustomTime struct {
time.Time
}
func (ct CustomTime) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format("2006-01-02"))), nil
}
func (ct *CustomTime) UnmarshalJSON(data []byte) error {
t, err := time.Parse(`"2006-01-02"`, string(data))
if err != nil {
return err
}
ct.Time = t
return nil
}
预编译结构体使用 jsoniter
等第三方库可提升 3-5 倍性能,但标准库通过以下方式优化:
• 字段缓存:首次解析后缓存反射结果
• 缓冲池:复用 bytes.Buffer
减少内存分配
var bufPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}
避免反射开销
对高频调用的结构体使用代码生成工具(如 easyjson
)生成序列化代码。
错误类型• json.SyntaxError
:语法错误(如缺失引号)
• json.UnmarshalTypeError
:类型不匹配
if err := json.Unmarshal(data, &obj); err != nil {
if serr, ok := err.(*json.SyntaxError); ok {
log.Printf("Syntax error at offset %d", serr.Offset)
}
}
调试工具
使用 json.Valid()
快速验证 JSON 合法性:
if !json.Valid(rawData) {
return errors.New("invalid JSON")
}