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

3 回复

哦……这已经是我第二次被“首字母大写才能导出”这件事给坑到了!!!

谢谢,问题解决了!我知道我的结构体里肯定有严重错误,但完全没想到是首字母大写的问题。你看,出于纯粹的沮丧,我甚至考虑从 JSON 切换到 YAML,结果同样的事情又发生了。

感谢你的快速回复。

更多关于Golang中struct转json生成空文档的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go 不使用像 publicprivate 这样的访问修饰符,而是通过首字母大写来标记一个名称对其他包可见。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,
	})
}

这样即使字段小写也能正确序列化,但通常建议直接使用公开字段。

回到顶部