Go语言中HTTP Get请求JSON转结构体切片及空切片问题排查
问题分析与解决方案
为什么holidays是空切片?
你定义的Response结构体和API返回的JSON结构完全不匹配,导致json.Unmarshal无法把数据解析到response.Data里,response.Data是空切片,后续循环自然不会往holidays里添加任何元素,最终输出空的[]。
Gov.uk API返回的JSON本质是键为地区名称、值为包含假日列表对象的Map,简化结构如下:
{ "england-and-wales": { "division": "england-and-wales", "events": [ {"title": "New Year’s Day", "date": "2024-01-01"} ] }, "scotland": { "division": "scotland", "events": [] } }
而你定义的Response结构体是包含Data切片的结构,和实际返回格式完全不符,所以解析失败。
如何将JSON转换为可用的结构体切片?
需要重新定义匹配JSON结构的结构体,解析后遍历Map里的每个地区对象,提取其中的假日事件到holidays切片。
修正后的代码如下:
package main import ( "encoding/json" "fmt" "log" "net/http" ) // 对应每个地区的假日数据结构 type RegionHoliday struct { Division string `json:"division"` Events []Bankholiday `json:"events"` } type Bankholiday struct { Title string `json:"title"` Date string `json:"date"` } func main() { resp, err := http.Get("https://www.gov.uk/bank-holidays.json") if err != nil { log.Fatal(err) } defer resp.Body.Close() // http.Get返回的resp.Body始终非nil,直接延迟关闭即可 // 用map接收整个JSON的键值对结构 var holidayMap map[string]RegionHoliday err = json.NewDecoder(resp.Body).Decode(&holidayMap) if err != nil { log.Fatal(err) } var holidays []Bankholiday // 遍历所有地区,将假日事件合并到切片中 for _, region := range holidayMap { holidays = append(holidays, region.Events...) } fmt.Println("holidays: ", holidays) }
关键修改说明:
- 结构体匹配JSON结构:用
map[string]RegionHoliday接收整个响应,RegionHoliday里的Events字段通过json:"events"标签和JSON里的events数组映射,确保解析正确。 - 高效解析方式:直接用
json.NewDecoder解析响应体,避免先把整个响应读入内存,更节省资源。 - 简化资源管理:去掉多余的
resp.Body非空判断,http.Get返回的响应体始终可以安全关闭。
内容的提问来源于stack exchange,提问作者lemonsrule101
相关产品推荐
相关产品推荐

