json.Marshal 功能详解

json.Marshal 是 Go 语言标准库 encoding/json 中的一个核心函数,用于将 Go 的数据结构序列化为 JSON 格式字节切片[]byte)。

基本功能

func Marshal(v interface{}) ([]byte, error)
  • 输入:任意 Go 值(结构体、map、切片、基本类型等)
  • 输出:JSON 格式的 []byte 和可能的错误

使用示例

基本示例

package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    user := User{1, "张三", 30}

    jsonData, err := json.Marshal(user)
    if err != nil {
        fmt.Println("JSON 编码错误:", err)
        return
    }

    fmt.Println(string(jsonData))
    // 输出: {"id":1,"name":"张三","age":30}
}

主要特性

1. 结构体标签控制

可以通过 json 标签控制字段名称和序列化行为:

type Product struct {
    ID       int     `json:"product_id"`       // 自定义字段名
    Name     string  `json:"name"`              // 常规字段
    Price    float64 `json:"price,omitempty"`   // 空值时不序列化
    InStock  bool    `json:"-"`                 // 忽略该字段
}

2. 支持的数据类型

  • 基本类型:int, float, string, bool
  • 复合类型:struct, map, slice, array
  • 指针:自动解引用
  • 实现了 json.Marshaler 接口的自定义类型

3. 特殊处理

  • 时间类型 time.Time 会转换为 RFC3339 格式字符串
  • 通道、函数和循环引用会导致错误

json.MarshalIndent 的区别

json.Marshal 的变体,用于生成格式化的 JSON:

jsonData, _ := json.MarshalIndent(user, "", "  ")
/*
输出:
{
  "id": 1,
  "name": "张三",
  "age": 30
}
*/

常见错误处理

data := make(chan int)
_, err := json.Marshal(data)
if err != nil {
    fmt.Println("错误:", err) // 错误: json: unsupported type: chan int
}

性能考虑

  1. 比直接字符串拼接更安全(正确处理特殊字符)
  2. 比模板引擎更高效
  3. 大量数据序列化时考虑使用 json.Encoder

json.Marshal 是 Go 中处理 JSON 序列化的基础工具,几乎所有的 Go Web 框架底层都使用它来处理 JSON 响应。