
go中结构体转json为空对象{},根本原因是字段未导出(首字母小写),导致encoding/json包无法通过反射访问字段值;只需将字段名首字母大写并配合json标签即可正确序列化与反序列化。
go中结构体转json为空对象{},根本原因是字段未导出(首字母小写),导致encoding/json包无法通过反射访问字段值;只需将字段名首字母大写并配合json标签即可正确序列化与反序列化。
在Go语言中,encoding/json包的序列化(json.Marshal)和反序列化(json.Unmarshal)均依赖反射机制读取或写入结构体字段。但Go的反射规则严格遵循其导出(exported)规则:只有首字母为大写的字段(即导出字段)才能被外部包(包括标准库encoding/json)访问;小写字母开头的字段属于包级私有(unexported),即使添加了json:"xxx"标签,也会被完全忽略。
你遇到的问题正是典型表现:
- 原始结构体 type Message { name string; things []string } 中,name 和 things 均为小写开头 → 全部未导出;
- json.Marshal(i) 无法读取任何字段值,返回空JSON对象 []byte{123, 125}(即"{}");
- json.Unmarshal 同样无法向私有字段赋值,解码后o的字段保持零值("" 和 nil切片),输出为 { []}。
✅ 正确做法:导出字段 + 显式JSON标签控制键名
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
type Message struct {
Name string `json:"name"`
Things []string `json:"things"`
}
- Name 和 Things 首字母大写 → 满足导出要求,可被json包访问;
- json:"name" 和 json:"things" 标签确保生成的JSON键名为小写,符合API命名惯例(如RESTful接口常用snake_case或camelCase);
- 标签不是必需的(若省略,JSON键将默认使用Go字段名Name/Things),但强烈推荐显式声明,以解耦Go命名规范与JSON协议约定。
完整可运行示例:
package main
import (
"encoding/json"
"fmt"
)
type Message struct {
Name string `json:"name"`
Things []string `json:"things"`
}
func main() {
i := Message{
Name: "Steel",
Things: []string{"Iron", "Carbon"},
}
fmt.Printf("Go value: %+v\n", i)
// 输出: Go value: {Name:"Steel" Things:["Iron" "Carbon"]}
b, err := json.Marshal(i)
if err != nil {
panic(err)
}
fmt.Printf("JSON bytes: %v\n", b)
fmt.Printf("JSON string: %s\n", string(b))
// 输出: {"name":"Steel","things":["Iron","Carbon"]}
var o Message
if err := json.Unmarshal(b, &o); err != nil {
panic(err)
}
fmt.Printf("Decoded: %+v\n", o)
// 输出: Decoded: {Name:"Steel" Things:["Iron" "Carbon"]}
}
⚠️ 注意事项与最佳实践:
- 导出性优先于标签:json:"xxx"仅控制键名映射,不能绕过导出规则。即使写成 name string \json:"name"``,该字段仍会被忽略。
- 类型一致性不可忽视:若JSON中某字段为数字(如"id": 123),结构体对应字段必须是int、int64等数值类型,而非string,否则反序列化会静默失败或报错。
- 嵌套结构体同理:若Things是自定义结构体切片,其内部字段也需全部导出。
- 错误处理务必检查:示例中使用if err := json.Unmarshal(...) { panic(err) }强调错误不可忽略——生产环境应记录日志并返回用户友好错误。
遵循这一原则,无论是Web API响应、配置文件序列化,还是RPC通信,都能确保JSON数据准确、可靠地在Go结构体与外部世界之间双向流转。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










