
在go中进行json序列化时,只有首字母大写的导出字段才能被json.marshal识别并输出,小写字段会被忽略,导致嵌套结构无法正确序列化。
在go中进行json序列化时,只有首字母大写的导出字段才能被json.marshal识别并输出,小写字段会被忽略,导致嵌套结构无法正确序列化。
Go 的 encoding/json 包遵循严格的可见性规则:仅导出(即首字母大写)的结构体字段才能被 JSON 编码/解码器访问。你原始代码中 Metadata.model、Texture.url 等字段均为小写开头(如 model, url, hash, metadata),属于非导出字段,因此 json.Marshal 会跳过它们,最终只得到空对象 {"SKIN":{}}。
要修复该问题,需将所有待序列化的字段名改为大驼峰命名(Exported Identifiers),并可选地通过 json 标签自定义键名以保持语义清晰:
package main
import (
"encoding/json"
"fmt"
)
type Metadata struct {
Model string `json:"model"` // 导出字段 + 显式标签
}
type Texture struct {
URL string `json:"url"`
Hash string `json:"hash"`
Metadata *Metadata `json:"metadata,omitempty"` // omitempty 表示值为 nil 时不输出
}
type Response struct {
SKIN *Texture `json:"SKIN"`
}
func main() {
response := Response{}
textures := &Texture{
URL: "http://ely.by",
Hash: "123123123123123123",
Metadata: &Metadata{
Model: "slim",
},
}
response.SKIN = textures
result, err := json.MarshalIndent(response, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(result))
}
运行后将输出符合预期的格式化 JSON:
{
"SKIN": {
"url": "http://ely.by",
"hash": "123123123123123123",
"metadata": {
"model": "slim"
}
}
}
⚠️ 注意事项:
- 字段名必须首字母大写(如 Model, URL, Hash),否则 JSON 包完全不可见;
- 使用 json:"xxx" 标签可控制 JSON 中的键名,提升可读性与兼容性;
- omitempty 是常用选项,避免空值(nil 指针、零值字符串等)出现在输出中;
- 若嵌套结构可能为 nil(如 *Metadata),确保业务逻辑能安全处理,或在序列化前做非空校验。
总结:Go 的 JSON 序列化依赖于 Go 的导出规则,而非字段类型或嵌套深度。只要所有层级的字段均正确导出并合理配置 json 标签,任意深度的嵌套结构均可无缝序列化。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











