跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何在 Go 中正确解码 JSON 数组到结构体切片

本文详解 go 语言中将 json 数组反序列化为结构体切片的关键要点:字段必须导出(首字母大写)、使用指针传递切片变量、并处理嵌套响应中的实际数据路径。 本文详解 go 语言中将 js on 数组反序列化为结构体切片的关键要点:字段必须导出(首字母大写)、使用指针传递切片变量、并处理嵌套响应中的实际数据路径。 在 Go 中解析来自外部服务(如 Google Apps Script)的 JSON 响应时,常见错误是结构体字段未导出或解码目标类型不匹配。你提供的原始数据本质上是一个嵌套结构:外层是 map[string]interface{}(含 @type 和 result 键),而真正需要的是 result 字段对应的 JSON 数组部分。 首先,确保你的结构体字段全部 导出 (即首字母大写),否则 encoding/ json 包无法访问和赋值:
type Case struct { ID int `json:"id"` CaseNumber string `json:"casenumber"` DateDelivered string `json:"datedelivered"` Judge string `json:"judge"` Court string `json:"court"` Location string `json:"location"` Accused string `json:"accused"` Prosecution string `json:"prosecution,omitempty"` // 可选字段,缺失时忽略 Judgment string `json:"judgment"` }
注意:我们添加了 json 标签以精确匹配 JSON 键名,并为 prosecution 添加 omitempty,使其在部分对象中缺失时不会报错。 接下来,关键在于 识别并提取 result 字段内容 。原始数据并非纯 JSON 数组,而是形如:
{ "@type": "type.googleapis.com/google.apps.script.v1.ExecutionResponse", "result": [...] }
因此不能直接 json.Unmarshal(rawData, &[]Case{}) —— 因为 rawData 是一个 map 的 JSON 表示,不是数组。你需要分两步处理: 先定义一个临时结构体或用 map[string]interface{} 解析外层; 提取 result 字段的字节流([]byte),再二次解码为 []Case。 推荐做法(清晰且类型安全): Find JSON Path Online Easily find JSON paths within JSON objects using our intuitive Json Path Finder 下载
type ExecutionResponse struct { Type string `json:"@type"` Result json.RawMessage `json:"result"` // 延迟解析 result 字段 } func parseCases(data []byte) ([]Case, error) { var resp ExecutionResponse if err := json.Unmarshal(data, &resp); err != nil { return nil, fmt.Errorf("failed to unmarshal outer response: %w", err) } var cases []Case if err := json.Unmarshal(resp.Result, &cases); err != nil { return nil, fmt.Errorf("failed to unmarshal result array: %w", err) } return cases, nil }
✅ 正确调用方式:
data := []byte(`{"@type":"...","result":[{"id":1,"casenumber":"Criminal Case 20 of 2012",...}...]}`) cases, err := parseCases(data) if err != nil { log.Fatal(err) } fmt.Printf("Parsed %d cases\n", len(cases))
⚠️ 常见错误提醒: ❌ json: cannot unmarshal object into Go value of type []Case:说明你传入的是整个对象 JSON(含 @type 和 result),而非 result 内部的数组 JSON; ❌ 字段小写(如 id int)会导致解码静默失败(值保持零值); ❌ 忘记对切片取地址(&cases)将导致解码无效果。 ? 进阶建议:若 result 结构稳定,可直接定义完整嵌套结构体;若需高灵活性,结合 json.RawMessage 实现按需解析。始终使用 json.Unmarshal 的错误返回进行校验,避免静默失败。 通过以上步骤,你就能可靠地从 Google Script 的响应中提取结构化案件数据,并在 Go 应用中安全使用。

相关文章