Golang中struct转json生成空文档的问题
Golang中struct转json生成空文档的问题 我已经尝试了在网上能找到的每一个示例,试图将我的自定义结构体序列化为JSON文档,但每个示例都返回一个空文档({}),我无法理解原因……
示例代码,包含我的结构体:
type dbCredsStruct struct {
hostname string `json:"hostname"`
rootUsr string `json:"rootusr"`
rootPasswd string `json:"rootpasswd"`
port int `json:"port"`
}
func creds2json(jsonFile string, creds dbCredsStruct) {
c := dbCredsStruct{hostname: "hostname", rootUsr: "rootusr", rootPasswd: "q1w2e3", port: 65432}
jStream, err := json.Marshal(c)
if err != nil {
fmt.Println("Error", err)
}
fmt.Println(string(jStream))
//os.WriteFile(jsonFile, jStream, 0644)
}
这里,为了简单起见,我忽略了creds2json()的参数,并手动用结构体填充了c。
fmt.Println()函数在这里将输出{}。
在调试器中,如果检查c,一切看起来都正常。jstream的类型是[]uint8,包含2个元素:uint8 123和uint8 125。
有人知道这是怎么回事吗?
更多关于Golang中struct转json生成空文档的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
哦……这已经是我第二次被“首字母大写才能导出”这件事给坑到了!!!
谢谢,问题解决了!我知道我的结构体里肯定有严重错误,但完全没想到是首字母大写的问题。你看,出于纯粹的沮丧,我甚至考虑从 JSON 切换到 YAML,结果同样的事情又发生了。
感谢你的快速回复。
更多关于Golang中struct转json生成空文档的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go 不使用像 public 或 private 这样的访问修饰符,而是通过首字母大写来标记一个名称对其他包可见。json 包无法看到你的 dbCredsStruct 中的 hostname 字段,因此该字段被忽略了。修复方法是重命名字段,使用大写字母:
type dbCredsStruct struct {
Hostname string `json:"hostname"`
RootUsr string `json:"rootusr"`
RootPasswd string `json:"rootpasswd"`
Port int `json:"port"`
}
问题在于结构体字段的可见性。在Go中,只有首字母大写的字段(公开字段)才能被json包序列化。你的结构体字段都是小写开头,因此json.Marshal无法访问它们,导致生成空JSON对象。
修改后的代码:
type dbCredsStruct struct {
Hostname string `json:"hostname"`
RootUsr string `json:"rootusr"`
RootPasswd string `json:"rootpasswd"`
Port int `json:"port"`
}
func creds2json(jsonFile string, creds dbCredsStruct) {
c := dbCredsStruct{
Hostname: "hostname",
RootUsr: "rootusr",
RootPasswd: "q1w2e3",
Port: 65432,
}
jStream, err := json.Marshal(c)
if err != nil {
fmt.Println("Error", err)
return
}
fmt.Println(string(jStream))
// 输出: {"hostname":"hostname","rootusr":"rootusr","rootpasswd":"q1w2e3","port":65432}
}
如果必须保持字段小写但需要序列化,可以使用自定义的MarshalJSON方法:
type dbCredsStruct struct {
hostname string
rootUsr string
rootPasswd string
port int
}
func (c dbCredsStruct) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"hostname": c.hostname,
"rootusr": c.rootUsr,
"rootpasswd": c.rootPasswd,
"port": c.port,
})
}
这样即使字段小写也能正确序列化,但通常建议直接使用公开字段。

