在Go语言开发中,使用json.Marshal把结构体转为JSON是很常见的操作。当结构体内包含另一个结构体字段,并且这个字段没有被赋值时,默认序列化结果会保留一个空对象。把字段声明为指针类型,就能在字段为nil时让json包自动忽略它,从而避免输出无意义的空结构体。

为什么普通结构体字段会输出空对象
先看一个普通结构体嵌套的例子。当Inner没有赋值时,序列化结果里仍然会出现"inner":{}。
package main
import (
"encoding/json"
"fmt"
)
type Inner struct {
Name string `json:"name"`
}
type Outer struct {
ID int `json:"id"`
Inner Inner `json:"inner"`
}
func main() {
o := Outer{ID: 1}
b, _ := json.Marshal(o)
fmt.Println(string(b))
}
运行后输出:
{"id":1,"inner":{}}
使用指针类型忽略空结构体
把Inner字段改为指针类型,当它为nil时,json.Marshal就会直接省略该字段。
package main
import (
"encoding/json"
"fmt"
)
type Inner struct {
Name string `json:"name"`
}
type Outer struct {
ID int `json:"id"`
Inner *Inner `json:"inner,omitempty"`
}
func main() {
o := Outer{ID: 1}
b, _ := json.Marshal(o)
fmt.Println(string(b))
}
此时输出为:
{"id":1}
关键点说明
- 字段类型写成*Inner而不是Inner,零值为nil
- 加上omitempty标签,确保即使是指针类型在赋值为非空结构体时正常输出,为空时省略
- 只有指针为nil时才会被忽略,若使用new(Inner)创建了空结构体指针,仍会输出空对象
需要主动忽略时的写法
如果某些场景下已经创建了结构体但想忽略,可以手动置为nil。
package main
import (
"encoding/json"
"fmt"
)
type Inner struct {
Name string `json:"name"`
}
type Outer struct {
ID int `json:"id"`
Inner *Inner `json:"inner,omitempty"`
}
func main() {
o := Outer{ID: 2, Inner: &Inner{}}
o.Inner = nil
b, _ := json.Marshal(o)
fmt.Println(string(b))
}
总结
将嵌套结构体字段声明为指针类型并配合omitempty,是Go里忽略空结构体最简洁的方法。它在写API响应结构、配置对象时非常实用,可以让JSON更干净,也减少前端不必要的判断。
Gojson.Marshal指针类型修改时间:2026-07-30 16:30:21