
本文详解 go 语言中解析 json 数组与单对象的常见误区,重点说明结构体定义、反序列化方式及输入格式匹配原则,并提供可运行示例与实用建议。
在 Go 中解析 JSON 时,输入 JSON 的实际结构必须与 Go 反序列化目标类型严格一致——这是绝大多数 json.Unmarshal 失败的根本原因。以问题中的数据为例:
[
{
"ShaId": "adf56a4d",
"Regions": [
{ "Name": "us-east-1a" }
]
}
]这是一个 JSON 数组([]object),因此必须使用切片([]ShaInfo)接收;若错误地用单个结构体变量(如 var data ShaInfo)去解析该数组,json.Unmarshal 将返回 invalid character '[' looking for beginning of value 或类似错误。
✅ 正确做法:按 JSON 结构定义 Go 类型并匹配解码目标
首先定义清晰、可导出的结构体(字段首字母大写):
type Region struct {
Name string `json:"Name"`
}
type ShaInfo struct {
ShaId string `json:"ShaId"`
Regions []Region `json:"Regions"`
}然后根据 JSON 输入选择对应解码方式:
▪ 场景一:输入是 JSON 数组(推荐用于批量数据)
content := `[{"ShaId": "adf56a4d", "Regions": [{"Name": "us-east-1a"}]}]`
var results []ShaInfo
if err := json.Unmarshal([]byte(content), &results); err != nil {
log.Fatal("解析 JSON 数组失败:", err)
}
fmt.Printf("解析成功,共 %d 条记录: %+v\n", len(results), results)
// 输出: 解析成功,共 1 条记录: [{ShaId:adf56a4d Regions:[{Name:us-east-1a}]}]▪ 场景二:输入是单个 JSON 对象(无需方括号)
content := `{"ShaId": "adf56a4d", "Regions": [{"Name": "us-east-1a"}]}`
var single ShaInfo
if err := json.Unmarshal([]byte(content), &single); err != nil {
log.Fatal("解析单个对象失败:", err)
}
fmt.Printf("单对象解析结果: %+v\n", single)
// 输出: 单对象解析结果: {ShaId:adf56a4d Regions:[{Name:us-east-1a}]}⚠️ 关键注意事项
- 结构体字段必须导出(首字母大写)且含 json 标签,否则 json 包无法访问和赋值;
- json.Unmarshal 的第二个参数必须是指针(&variable),否则无效果;
- 不要强行“套用”切片类型解析单对象,也不要用单结构体解析数组——Go 不会自动转换容器类型;
- 若上游 API 返回格式不确定(有时单对象、有时数组),可先用 json.RawMessage 做预判,或统一要求服务端返回标准数组格式(更健壮);
- 使用 Go Playground 快速验证时,请确保 content 字符串与真实响应完全一致(包括空格、引号、嵌套层级)。
掌握“JSON 形态 → Go 类型 → Unmarshal 目标”三者严格对应的原则,即可彻底避免 Unable to parse JSON array 类错误。










