在Go语言开发中,将结构体转换为标准JSON格式输出到控制台是调试和数据验证的常用操作,核心依赖官方标准库的encoding/json包实现序列化逻辑。

基础序列化实现
使用json.Marshal函数可以将结构体实例转换为JSON字节数组,再通过string转换后打印到控制台,这是最基础的实现方式。
package main
import (
"encoding/json"
"fmt"
)
// 定义用户结构体
type User struct {
Name string
Age int
Email string
}
func main() {
// 创建结构体实例
user := User{
Name: "张三",
Age: 25,
Email: "test@ipipp.com",
}
// 序列化为JSON字节数组
jsonBytes, err := json.Marshal(user)
if err != nil {
fmt.Println("序列化失败:", err)
return
}
// 转换为字符串输出到控制台
fmt.Println(string(jsonBytes))
}
上述代码运行后输出的JSON内容是紧凑格式,所有字段和值连在一起,可读性较差,适合程序间传输使用。
格式化输出提升可读性
如果需要输出带缩进的标准JSON格式,适合人工查看调试,可以使用json.MarshalIndent函数,该函数支持指定前缀和缩进字符串。
package main
import (
"encoding/json"
"fmt"
)
type Product struct {
ID int
Name string
Price float64
}
func main() {
product := Product{
ID: 1001,
Name: "无线鼠标",
Price: 89.9,
}
// 序列化并添加缩进,前缀为空,缩进用两个空格
jsonBytes, err := json.MarshalIndent(product, "", " ")
if err != nil {
fmt.Println("序列化失败:", err)
return
}
fmt.Println(string(jsonBytes))
}
运行上述代码后,控制台会输出层级清晰的JSON内容,每个字段单独占一行,嵌套结构也会正确缩进。
结构体字段标签配置
默认情况下,JSON序列化后的字段名和结构体字段名一致,首字母大写。如果需要自定义字段名、忽略某些字段或者处理空值,可以通过结构体标签实现。
常用标签说明
- json:"field_name":指定序列化后的JSON字段名,替代结构体原字段名
- json:"-":忽略该字段,不参与序列化
- json:"field_name,omitempty":当字段值为零值时,序列化时忽略该字段
package main
import (
"encoding/json"
"fmt"
)
type Order struct {
// 自定义JSON字段名为order_id
OrderID int `json:"order_id"`
// 忽略该字段,不输出到JSON
InternalCode string `json:"-"`
// 零值时忽略该字段
Remark string `json:"remark,omitempty"`
// 嵌套结构体,默认会展开序列化
UserInfo User `json:"user_info"`
}
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
order := Order{
OrderID: 20240501,
InternalCode: "IC_001",
Remark: "", // 零值,会被忽略
UserInfo: User{
Name: "李四",
Age: 30,
},
}
jsonBytes, err := json.MarshalIndent(order, "", " ")
if err != nil {
fmt.Println("序列化失败:", err)
return
}
fmt.Println(string(jsonBytes))
}
上述代码中,InternalCode字段会被忽略,Remark字段因为是空字符串零值也会被忽略,最终输出的JSON只包含order_id和user_info两个字段。
特殊类型处理
如果结构体中包含时间类型、切片、map等特殊类型,默认序列化会按照内置规则处理,比如time.Time类型会序列化为RFC3339格式的时间字符串。
package main
import (
"encoding/json"
"fmt"
"time"
)
type Task struct {
TaskID int `json:"task_id"`
Content string `json:"content"`
CreateTime time.Time `json:"create_time"`
Tags []string `json:"tags"`
}
func main() {
task := Task{
TaskID: 1,
Content: "完成项目文档编写",
CreateTime: time.Now(),
Tags: []string{"工作", "文档"},
}
jsonBytes, err := json.MarshalIndent(task, "", " ")
if err != nil {
fmt.Println("序列化失败:", err)
return
}
fmt.Println(string(jsonBytes))
}
如果需要自定义时间格式,可以自定义类型实现json.Marshaler接口,重写MarshalJSON方法即可。
常见问题排查
- 如果结构体字段首字母是小写,json.Marshal无法访问该字段,序列化后不会包含该字段,需要保证字段可导出。
- 如果序列化返回错误,通常是结构体中存在无法序列化的类型,比如函数类型、通道类型等,需要排除这些字段。
- 如果输出的JSON中文出现乱码,通常是控制台编码问题,Go序列化的JSON默认是UTF-8编码,调整控制台编码为UTF-8即可解决。
注意:所有需要序列化的结构体字段必须是可导出的,也就是首字母大写,否则encoding/json包无法读取字段值,会导致该字段丢失。
GoJSON结构体encoding_json修改时间:2026-06-29 00:39:16