为什么需要response.Body.Close()
主要是为了避免内存泄漏的问题, 如果 response 不关闭,会导致内存泄漏。
关闭 http 响应
当你使用标准http库发起请求时,你得到一个http的响应变量。如果你不读取响应主体,你依旧需要关闭它。注意对于空的响应你也一定要这么做。对于新的Go开发者而言,这个很容易就会忘掉。
先看段代码:
package main import ( "fmt" "net/http" "io/ioutil" ) func main() { resp, err := http.Get("https://api.ipify.org?format=json") defer resp.Body.Close()//not ok if err != nil { fmt.Println(err) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }
上面的代码有没有问题呢?
假设上面的代码请求失败了, resp
肯能会是 nil
,这样执行就会出现一个 runtime panic
, 因为 defer resp.Body.Close()//not
这个 resp 是个nil ,肯定就 panic
了。
那怎么办?
通过在http响应错误处理中添加一个关闭non-nil
响应主体的的调用来修复这个问题。另一个方法是使用一个defer
调用来关闭所有失败和成功的请求的响应主体。
import ( "fmt" "net/http" "io/ioutil" ) func main() { resp, err := http.Get("https://api.ipify.org?format=json") if resp != nil { defer resp.Body.Close() } if err != nil { fmt.Println(err) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }