用 Go 调第三方天气 API 的核心是:选 resty/v2 作 HTTP 客户端(自带超时、重试、自动 JSON 解析);正确拼接 HTTPS 请求 URL(注意 base URL 末尾无斜杠、q 参数、appid 在 query 中、中文需 url.QueryEscape);安全解析 JSON(字段名严格匹配、嵌套结构拆解定义、单位转换、检查 status code)。

用 Go 调第三方天气 API 做命令行查询,核心就三件事:选对 HTTP 客户端、正确拼接请求 URL、安全解析 JSON 响应。别碰 net/http 自己写重试和超时,也别用没维护的旧包。
怎么选 HTTP 客户端:别自己封装 http.Client,直接用 resty
原生 http.Client 写起来啰嗦,容易漏设超时、没自动重试、JSON 解析要手动 io.ReadAll + json.Unmarshal。用 resty(v2)省心又健壮:
-
resty默认带 30 秒超时,可显式调用.SetTimeout(10 * time.Second)防卡死 - 加一行
.SetRetryCount(2)就能自动重试失败请求(比如网络抖动) -
.Get()返回结构体指针,不用自己json.Unmarshal;错误时err明确是网络错还是状态码非 2xx - 注意:别用
github.com/go-resty/resty(v1 已归档),必须用github.com/go-resty/resty/v2
怎么拼天气 API 请求:看清文档里的 q、appid 和 base URL
主流免费天气 API(如 OpenWeatherMap)要求把城市名或经纬度作为参数传过去。常见踩坑点不是代码,是 URL 拼错:
- base URL 必须用 HTTPS,且末尾不带
/(比如https://api.openweathermap.org/data/2.5/weather) - 城市查询参数是
q=shanghai,不是city=shanghai;IP 查询用q=ip+lat/lon参数 -
appid是必填 query 参数,不能放 header;测试时别用123456789这类假 key,会返回401 Unauthorized - 中文城市名要 URL 编码,
url.QueryEscape("北京")得套一层,否则返回404 Not Found
怎么解析响应 JSON:定义 struct 字段名必须和 JSON key 严格匹配
Go 的 json 包默认按字段名大小写+tag 匹配,OpenWeatherMap 返回的 JSON key 全小写带下划线,比如 "main": {"temp": 292.15}:
立即学习“go语言免费学习笔记(深入)”;
- struct 字段名不能驼峰(
Temp),得写成Temp float64 `json:"temp"` - 嵌套结构必须拆开定义,不能用
map[string]interface{}—— 那样后续取值要反复断言,易 panic - 温度单位默认是 Kelvin,转摄氏度要减 273.15;API 文档里写了
units=metric可直接返回 ℃,加到 query 里更省事 - 如果 response status code 是
404但没检查resp.StatusCode(),程序会继续解析空 body,触发invalid character 'N' looking for beginning of value
怎么处理命令行输入:用 flag 包,但别忽略空参数和帮助提示
用户执行 ./weather -city "" 或直接 ./weather,程序不能 panic 或静默退出:
- 用
flag.StringVar(&city, "city", "", "城市名,如 shanghai 或 beijing"),然后flag.Parse()后立刻检查if city == "" - 加
flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s -city <name>\n", os.Args[0]) }</name>,不然用户输错参数看不到提示 - 别用
os.Args[1]手动取参 —— 没参数时会 panic,也不支持-h或--help - 如果想支持位置参数(如
./weather shanghai),得用flag.Args(),但优先推荐 flag 形式,更清晰可控
最常被跳过的其实是错误路径:比如网络不通时没打印具体 err.Error(),或者 JSON 字段缺失时没给默认值(Temp 字段为空导致 0.0℃ 误报)。真实场景里,这些比“怎么发起请求”更影响可用性。










