Go语言中嵌套结构API响应解析失败问题求助
问题诊断与解决方法
你的问题核心在于结构体定义完全不匹配第二种API响应的嵌套结构,同时还有一个容易忽略的字段标签错误,这两个问题共同导致了解析后结构体为空。
先拆解两种响应的结构差异:
- 第一种响应是直接的对象数组:
[]{"date": "...", "user": "...", "url": "..."} - 第二种响应是外层对象包裹着对象数组:
{"urls": []{"date": "...", "user": "...", "url": "..."} }
第一步:修正字段标签错误
先看你第一种响应的结构体,你写的字段标签json:"urls"和JSON里的"url"字段不匹配,这是隐性错误。首先要修正标签,同时给结构体起更清晰的名字:
// 单个URL条目结构体,匹配JSON里的单个对象 type UrlEntry struct { Date string `json:"date"` User string `json:"user"` Url string `json:"url"` // 修正标签为"url",和JSON字段对应 }
第二步:定义匹配嵌套结构的外层结构体
第二种响应的外层是一个包含urls字段的对象,这个字段的值是UrlEntry类型的数组,所以需要定义一个外层结构体来包裹:
// 匹配第二种嵌套响应的结构体 type NestedUrlResponse struct { Urls []UrlEntry `json:"urls"` // 字段标签"urls"对应外层JSON的键 }
第三步:修改解析逻辑
针对第二种响应,你需要把json.Unmarshal的目标改成NestedUrlResponse类型的变量,而不是原来的url类型(那个是[]urls,和嵌套结构不匹配):
resp, err := http.Get("https://url") if err != nil { fmt.Println("No response from request") return // 记得处理错误,不要忽略 } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) // 注意:ioutil.ReadAll在Go 1.16+已被废弃,改用io.ReadAll if err != nil { fmt.Println("Failed to read response body:", err) return } // 针对第二种嵌套响应解析 var nestedResp NestedUrlResponse err = json.Unmarshal(body, &nestedResp) if err != nil { fmt.Println("Failed to unmarshal JSON:", err) return } // 现在nestedResp.Urls就是你需要的数组了 fmt.Println(nestedResp.Urls)
额外:兼容两种响应的小技巧
如果你的API可能返回两种格式,可以先尝试解析其中一种,失败后再解析另一种:
var entries []UrlEntry err = json.Unmarshal(body, &entries) if err != nil { // 第一种解析失败,尝试第二种嵌套结构 var nestedResp NestedUrlResponse err = json.Unmarshal(body, &nestedResp) if err != nil { fmt.Println("Failed to unmarshal both formats:", err) return } entries = nestedResp.Urls } // 现在entries里就是解析后的结果
内容的提问来源于stack exchange,提问作者ofashow
相关产品推荐
相关产品推荐

