Go 中结构体无法序列化为 JSON 的原因及解决方案
技术百科
霞舞
发布时间:2025-12-26
浏览: 次 go 的 `json.marshal` 只能序列化首字母大写的导出字段,小写开头的结构体字段(如 `local_address`)属于未导出成员,会被忽略,导致输出空对象 `{}`。解决方法是将字段名首字母大写并添加 json 标签,或自定义 `marshaljson` 方法。
在 Go 语言中,JSON 序列化依赖于 字段的可见性(exported/unexported),而非字段是否被显式标记。encoding/json 包运行在独立包内,它无法访问非导出(即小写开头)的结构体字段——这是 Go 的基础封装机制决定的。因此,原始代码中所有字段(如 local_address, local_port 等)均为小写开头,json.Marshal 对它们“视而不见”,最终只得到一个空 JSON 对象 {}。
✅ 正确做法:将字段名首字母大写,并推荐添加 json 标签以精确控制键名与行为:
type Configitem struct {
LocalAddress string `json:"local_address"`
LocalPort int `json:"local_port"`
Method string `json:"method"`
Password string `json:"password"`
Server string `json:"server"`
ServerPort string `json:"server_port"`
Timeout int `json:"timeout"`
}
type GuiConfig struct {
Configs []*Configitem `json:"configs"`
Index int `json:"index"`
}修改后,完整可运行示例:
package main
import (
"encoding/json"
"fmt"
)
type Configitem struct {
LocalAddress string `json:"local_address"`
LocalPort int `json:"local_port"`
Method string `json:"method"`
Password string `json:"password"`
Server string `json:"server"`
ServerPort string `json:"server_port"`
Timeout int `json:"timeout"`
}
type GuiConfig struct {
Configs []*Configitem `json:"configs"`
Index int `json:"index"`
}
func main() {
item1 := &Configitem{
LocalAddress: "eouoeu",
LocalPort: 111,
Method
: "eoeoue",
Password: "ouoeu",
Server: "oeuoeu",
ServerPort: "qoeueo",
Timeout: 3333,
}
config1 := &GuiConfig{
Index: 1,
Configs: []*Configitem{item1},
}
data, err := json.Marshal(config1)
if err != nil {
panic(err)
}
fmt.Println(string(data))
// 输出:{"configs":[{"local_address":"eouoeu","local_port":111,"method":"eoeoue","password":"ouoeu","server":"oeuoeu","server_port":"qoeueo","timeout":3333}],"index":1}
}⚠️ 注意事项:
- 字段名必须以大写字母开头(如 LocalAddress),否则即使加了 json 标签也无效;
- json 标签中的值(如 "local_address")定义了 JSON 输出的键名,支持别名、忽略("-")和条件省略(",omitempty");
- 若因设计需要保留字段私有性(不导出),可实现 MarshalJSON() ([]byte, error) 方法来自定义序列化逻辑,但会增加维护成本,一般不推荐;
- 嵌套结构体同理:所有层级中参与 JSON 序列化的字段都必须是导出字段。
总结:Go 的 JSON 序列化严格遵循“导出即可见”原则。养成首字母大写 + 显式 json 标签的习惯,是编写健壮、可维护序列化代码的关键实践。
# ai
# 这是
# 解决方法
# 均为
# 自定义
# 而非
# word
# js
# json
# go
# Error
# 对象
# 序列化
# git
# igs
# 封装
# 结构体
# 字段名
# 首字母
# 视而不见
# 键名
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win10怎么设置开机密码_Windows10账户
- Win11右键反应慢怎么办 Win11优化右键菜单
- 如何在Golang中修改数组元素_通过指针实现原地
- Win11关机快捷键是什么_Win11快速关机方法
- ACF 教程:正确更新嵌套在多层 Group 字段
- MAC如何设置网卡MAC地址克隆_MAC终端修改物
- 手机php文件怎么变成mp4_安卓苹果打开php转
- Linux怎么查找死循环进程_Linux系统负载分
- Django 密码修改后会话失效的解决方案
- Win10怎样清理C盘浏览器缓存_Win10清理浏
- Python对象生命周期管理_创建销毁解析【教程】
- Win10怎样卸载自带Edge_Win10卸载Ed
- Python文件和流处理指南_高效读写大体积数据文
- Win11怎么退出微软账户_切换Win11为本地账
- 如何使用Golang实现多重错误处理_Golang
- 如何在 Python 测试中动态配置 @backo
- Go 中 defer 在 goroutine 内部
- 如何在Golang中捕获HTTP服务器错误_Gol
- 网站内页做seo排名怎么做?
- 如何在 Go 中创建包含 map 的 slice(
- Python技术债务管理_长期维护解析【教程】
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- 如何在同包不同文件中正确引用 Go 结构体
- Linux怎么禁止Root用户远程登录_Linux
- Win11麦克风没声音怎么设置_Win11麦克风权
- Windows如何设置登录时的欢迎屏幕背景?(锁屏
- Linux如何使用grep搜索文件内容_Linux
- 如何在Golang中实现自定义Benchmark_
- Win11怎么关闭自动维护 Win11禁用系统自动
- Python与MongoDB NoSQL开发实战_
- Win11怎么更改输入法顺序_Win11调整语言首
- 如何使用Golang开发简单的聊天室消息存储_Go
- c++中的Tag Dispatching是什么_c
- Windows10如何更改开机密码_Win10登录
- Win11怎么更改电脑密码_Windows 11修
- Windows怎样关闭Edge新标签页广告_Win
- Win10文件历史记录怎么用 Win10开启自动备
- PHP怎么接收URL中的锚点参数_获取#后面参数值
- Win11截图快捷键是什么_Win11自带截图工具
- Win11怎么恢复误删照片_Win11数据恢复工具
- Windows蓝屏错误0x0000001E怎么修复
- 如何使用Golang反射将map转换为struct
- 如何使用正则表达式批量替换重复的星号-短横模式为固
- 如何在Mac上搭建Golang开发环境_使用Hom
- c++如何打印函数堆栈信息_c++ backtra
- Win11怎么更改默认打开方式_Win11关联文件
- Win11怎么开启远程桌面连接_Windows11
- Python数据挖掘进阶教程_分类回归与聚类案例解
- c++怎么使用std::tuple存储多元组数据_
- c++中如何进行二进制文件读写_c++ read与

: "eoeoue",
Password: "ouoeu",
Server: "oeuoeu",
ServerPort: "qoeueo",
Timeout: 3333,
}
config1 := &GuiConfig{
Index: 1,
Configs: []*Configitem{item1},
}
data, err := json.Marshal(config1)
if err != nil {
panic(err)
}
fmt.Println(string(data))
// 输出:{"configs":[{"local_address":"eouoeu","local_port":111,"method":"eoeoue","password":"ouoeu","server":"oeuoeu","server_port":"qoeueo","timeout":3333}],"index":1}
}
QQ客服