
go语言中使用json.unmarshal解析json时返回空值,通常是因为结构体字段未导出(首字母小写),导致json包无法访问和赋值;只需将字段名首字母大写并保持json标签正确即可解决。
go语言中使用json.unmarshal解析json时返回空值,通常是因为结构体字段未导出(首字母小写),导致json包无法访问和赋值;只需将字段名首字母大写并保持json标签正确即可解决。
在Go中,只有首字母大写的导出字段(exported fields) 才能被外部包(如 encoding/json)访问和设置值。而原始代码中定义的结构体字段(id、name 等)全部为小写开头,属于未导出字段,因此 json.Unmarshal 读取成功但实际未填充任何数据,最终返回全零值的切片(即“空白值”)。
✅ 正确做法是:将结构体字段名改为大驼峰命名(如 Id、Name),同时通过 json 标签精确映射 JSON 中的键名:
type Bands struct { // 建议类型名也首字母大写(符合Go命名规范)
Id string `json:"id"`
Name string `json:"name"`
Location string `json:"location"`
Year string `json:"year"`
}⚠️ 注意事项:
- 结构体类型名(如 Bands)也应大写,否则无法在 main 包外使用(本例虽在同包,但属良好实践);
- ioutil.ReadFile 已在 Go 1.16+ 中弃用,推荐改用 os.ReadFile;
- json.Unmarshal 返回错误需显式检查,否则静默失败难以调试;
- 若JSON字段可能缺失或为null,可考虑使用指针类型(如 *string)或自定义UnmarshalJSON方法。
优化后的完整示例:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"encoding/json"
"fmt"
"os"
)
type Bands struct {
Id string `json:"id"`
Name string `json:"name"`
Location string `json:"location"`
Year string `json:"year"`
}
func main() {
bands := getBands()
fmt.Printf("Parsed %d band(s):\n", len(bands))
for _, b := range bands {
fmt.Printf("- %s (%s), %s, %s\n", b.Name, b.Id, b.Location, b.Year)
}
}
func getBands() []Bands {
raw, err := os.ReadFile("../data/bands.json")
if err != nil {
fmt.Fprintf(os.Stderr, "failed to read JSON file: %v\n", err)
os.Exit(1)
}
var result []Bands
if err := json.Unmarshal(raw, &result); err != nil {
fmt.Fprintf(os.Stderr, "failed to parse JSON: %v\n", err)
os.Exit(1)
}
return result
}运行后将正确输出:
Parsed 3 band(s): - The Beatles (1), NY, 2012 - Nirvana (2), NY, 2010 - Metallica (3), NY, 1980
总结:Go 的 JSON 反序列化依赖字段的可导出性,而非标签本身——json 标签仅指定映射关系,真正决定能否赋值的是字段是否以大写字母开头。这是初学者最常见的陷阱之一,务必养成导出字段 + 显式错误处理的习惯。

















