
本文详解 go 语言中解析嵌套于 json 数组中的 api 响应(如 coinmarketcap v1 接口),重点解决因结构体类型与 json 根节点不匹配导致的解析失败问题,并提供健壮的错误处理与类型适配方案。
本文详解 go 语言中解析嵌套于 json 数组中的 api 响应(如 coinmarketcap v1 接口),重点解决因结构体类型与 json 根节点不匹配导致的解析失败问题,并提供健壮的错误处理与类型适配方案。
在 Go 中调用 RESTful API 并解析 JSON 响应时,一个常见却容易被忽略的关键点是:JSON 响应的顶层结构必须与 Go 结构体变量的类型严格匹配。以 https://api.coinmarketcap.com/v1/ticker/ethereum 为例,其响应是一个包含单个对象的 JSON 数组(即 [ {...} ]),而非直接的对象({...})。若仍使用 new(CoinMarketCapData) 创建单个结构体实例并传入 json.Decode(),解码器将无法匹配数组起始符 [,最终静默失败——字段保持零值(如空字符串、0、0.0),且不报错(除非显式检查返回的 error)。
正确做法是:将目标变量声明为切片(slice),并传入其地址。因为 json.Decoder.Decode() 要求传入一个可修改的指针,而切片本身是引用类型,需用 &priceData 确保解码器能向底层数组写入数据。
以下是修正后的完整示例:
package main
import (
"encoding/json"
"net/http"
"log"
)
type CoinMarketCapData struct {
Id string `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Rank int `json:"rank"`
PriceUSD float64 `json:"price_usd"`
PriceBTC float64 `json:"price_btc"`
Volume24hUSD float64 `json:"24h_volume_usd"`
MarketCapUSD float64 `json:"market_cap_usd"`
AvailableSupply float64 `json:"available_supply"`
TotalSupply float64 `json:"total_supply"`
PercentChange1h float32 `json:"percent_change_1h"`
PercentChange24h float32 `json:"percent_change_24h"`
PercentChange7d float32 `json:"percent_change_7d"`
}
func getJson(url string, target interface{}) error {
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
req.Header.Set("Accept", "application/json") // 更准确:用 Accept 而非 Content-Type
r, err := client.Do(req)
if err != nil {
return err
}
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
func main() {
url := "https://api.coinmarketcap.com/v1/ticker/ethereum"
priceData := make([]CoinMarketCapData, 0) // 初始化为空切片
err := getJson(url, &priceData) // 关键:传 &slice
if err != nil {
log.Fatalf("HTTP 或 JSON 解析失败: %v", err)
}
if len(priceData) == 0 {
log.Fatal("API 响应为空数组")
}
log.Printf("Ethereum Id: %s, Name: %s, Price (USD): $%.2f",
priceData[0].Id, priceData[0].Name, priceData[0].PriceUSD)
}
⚠️ 关键注意事项:
- 结构体字段标签(struct tags)必不可少:CoinMarketCap 的字段名含下划线(如 price_usd),Go 默认按首字母大写导出字段名匹配,因此必须通过 `json:"price_usd"` 显式映射。
- 始终检查 getJson 返回的 error:网络请求或 JSON 语法错误均会在此处暴露,忽略它将导致调试困难。
- 避免 http.NewRequest 中的 _ 忽略错误:应显式处理创建请求失败的情况(如 URL 格式错误)。
- Content-Type 请求头不适用于 GET:应改为设置 Accept: application/json,表明客户端期望 JSON 响应。
- API 已弃用提示:api.coinmarketcap.com/v1 已于 2018 年停用,生产环境请迁移至 v2 API 并使用 API Key 认证;本例仅作技术原理演示。
总结:解析 JSON 的核心原则是「结构一致」——数组响应 → 切片变量 + 取地址;对象响应 → 结构体指针。结合字段标签、错误检查与规范 HTTP 头,即可稳健处理各类第三方 API 数据。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











