Go 中的 json.Encoder
功能详解
json.Encoder
是 Go 标准库 encoding/json
中提供的高效 JSON 编码工具,与 json.Marshal
相比,它更适合流式数据或需要直接写入输出流(如 HTTP 响应)的场景。
基本用法
1. 创建 Encoder
import (
"encoding/json"
"os"
)
func main() {
// 通常包装一个 io.Writer (如文件、网络连接等)
enc := json.NewEncoder(os.Stdout) // 输出到标准输出
}
2. 编码数据
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
user := User{1, "张三"}
// 直接编码到输出流
if err := enc.Encode(user); err != nil {
panic(err)
}
// 输出: {"id":1,"name":"张三"}
核心特性
1. 流式处理(内存高效)
// 适合处理大数据集
users := []User{
{1, "Alice"},
{2, "Bob"},
{3, "Charlie"},
}
for _, user := range users {
if err := enc.Encode(user); err != nil {
log.Fatal(err)
}
// 每次编码后立即写入,不占用大内存
}
2. 自定义配置
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ") // 设置缩进(美化输出)
enc.SetEscapeHTML(false) // 禁用HTML字符转义
3. 直接写入 HTTP 响应(Web开发常用)
func handler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{
"status": "success",
"message": "操作成功",
}
w.Header().Set("Content-Type", "application/json")
enc := json.NewEncoder(w)
if err := enc.Encode(data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
与 json.Marshal
的关键区别
特性 | json.Encoder |
json.Marshal |
---|---|---|
输出目标 | 直接写入 io.Writer |
返回 []byte |
内存使用 | 流式处理,更节省内存 | 需要完整内存存储结果 |
使用场景 | HTTP 响应、大文件写入 | 需要中间 JSON 数据的场景 |
额外功能 | 可设置缩进、HTML转义等 | 无 |
错误处理 | 每次 Encode() 返回错误 |
单次返回错误 |
高级用法
1. 自定义 JSON 字段处理
type CustomTime time.Time
func (ct CustomTime) MarshalJSON() ([]byte, error) {
return []byte(`"` + time.Time(ct).Format("2006/01/02") + `"`), nil
}
// 使用时会自动调用自定义的 MarshalJSON 方法
2. 处理特殊数据类型
enc.SetEscapeHTML(false) // 默认true,会转义 &, <, > 等字符
3. 性能优化技巧
// 复用 buffer 提高性能
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
// 预热编码器(避免首次编码的初始化开销)
enc.Encode(nil)
buf.Reset()
实际应用场景
HTTP API 响应:
func JSONResponse(w http.ResponseWriter, statusCode int, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) json.NewEncoder(w).Encode(data) }
日志记录:
func logJSON(data interface{}) { enc := json.NewEncoder(logFile) enc.SetIndent("", " ") enc.Encode(data) }
大数据处理:
// 逐行处理大JSON文件 for _, bigData := range hugeDataset { if err := enc.Encode(bigData); err != nil { // 处理错误 } // 写入换行符或其他分隔符 out.Write([]byte("\n")) }
json.Encoder
是处理 JSON 输出的高效工具,特别适合网络编程和需要控制内存使用的场景。