
本文介绍在 Go 中通过定义包装结构体(wrapper struct)的方式,将原有结构体作为字段嵌入,从而在 JSON 序列化时自动形成嵌套结构(如 "fields": {…}),并确保字段名、标签和可导出性符合预期。
本文介绍在 go 中通过定义包装结构体(wrapper struct)的方式,将原有结构体作为字段嵌入,从而在 json 序列化时自动形成嵌套结构(如 `"fields": {…}`),并确保字段名、标签和可导出性符合预期。
要实现将 my_struct 实例嵌套进 "fields" 字段,并额外添加 "meta" 字段,关键在于:定义一个可导出的包装结构体,显式指定 JSON 字段名,并正确使用结构体字面量初始化。
首先,注意原结构体 my_struct 的字段首字母为小写(First, Second, Number),这使其在包外不可见——但更重要的是,Go 的 json 包仅序列化导出(大写首字母)字段。因此,即使你用小写字段加了 json:"first" 标签,该字段本身也必须是导出的,否则 json.Marshal 会忽略它。
✅ 正确做法:修正原始结构体字段名为导出形式(首字母大写),并保留 JSON 标签:
type MyStruct struct {
First string `json:"first"`
Second string `json:"second"`
Number int `json:"number"`
}
接着,定义包装结构体 WrappedOutput,其中 Fields 字段对应 "fields" 键,Meta 对应 "meta" 键(注意:字段名必须导出,JSON 标签控制输出键名):
type WrappedOutput struct {
Fields MyStruct `json:"fields"`
Meta string `json:"meta"`
}
完整示例代码如下:
package main
import (
"encoding/json"
"fmt"
)
type MyStruct struct {
First string `json:"first"`
Second string `json:"second"`
Number int `json:"number"`
}
type WrappedOutput struct {
Fields MyStruct `json:"fields"`
Meta string `json:"meta"`
}
func main() {
// 原始数据
output := MyStruct{
First: "my_string",
Second: "another_string",
Number: 2,
}
// 封装进新结构体
wrapped := WrappedOutput{
Fields: output,
Meta: "data",
}
// 序列化
data, err := json.MarshalIndent(wrapped, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
输出结果(格式化后):
{
"fields": {
"first": "my_string",
"second": "another_string",
"number": 2
},
"meta": "data"
}
⚠️ 注意事项:
- 结构体字段名必须首字母大写(导出),否则
json包无法访问; -
json标签中的字符串决定最终 JSON 键名,与 Go 字段名无关; - 若需动态嵌套或字段名不固定,可考虑使用
map[string]interface{},但会失去类型安全和编译期检查; - 使用
json.MarshalIndent可提升调试时的可读性(非必需)。
这种封装方式简洁、类型安全、易于维护,是 Go 中处理 JSON 嵌套结构的标准实践。











