
在go中执行http请求时,必须先检查错误再defer关闭响应体,否则可能因resp为nil导致panic;正确做法是获取响应后立即判断err是否非nil,确认无误后再defer resp.body.close()。
在go中执行http请求时,必须先检查错误再defer关闭响应体,否则可能因resp为nil导致panic;正确做法是获取响应后立即判断err是否非nil,确认无误后再defer resp.body.close()。
在Go语言的HTTP客户端编程中,http.Get() 的返回值为 ( *http.Response, error )。根据Go的惯用法,当调用失败时,resp 会被设为 nil,而 err 包含具体错误信息。若此时直接执行 defer resp.Body.Close(),由于 resp 为 nil,程序将在运行时触发 panic: runtime error: invalid memory address or nil pointer dereference。
✅ 正确顺序如下:
resp, err := http.Get("https://www.google.com")
if err != nil {
log.Printf("HTTP request failed: %v", err)
return err // 或适当处理错误(如返回、重试、fallback等)
}
defer resp.Body.Close() // 此时 resp 必然非nil,可安全defer
⚠️ 注意事项:
- defer 语句虽延迟执行,但其表达式(resp.Body.Close())在 defer 语句出现时即求值——因此必须确保 resp 和 resp.Body 当前有效;
- 即使后续逻辑发生panic或提前return,defer 仍会执行,从而保证资源释放;
- 若需读取响应体(如 io.ReadAll(resp.Body)),应在 defer resp.Body.Close() 之后进行,避免提前关闭;
- 对于更复杂的场景(如自定义 http.Client、设置超时、重试机制),该原则依然适用:先验错,再defer,后使用。
总结:Go强调显式错误处理和确定性资源管理。牢记“获取 → 检错 → defer清理 → 使用”的四步节奏,既是避免panic的关键,也是写出健壮、可维护HTTP客户端代码的基础实践。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











