在以下代码中,在错误情况下也有必要关闭响应主体:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
defer res.Body.Close()
在以下代码中,在错误情况下也有必要关闭响应主体:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
defer res.Body.Close()
一般概念是,当一个函数(或方法)有多个返回值(其中一个是error
)时,应该首先判断错误,并且只有在错误是nil
的情况下才会继续.如果存在error
,则函数应为其他(非错误)值返回零值.如果该函数的行为不同,则应对其进行记录.http.Get()
不记录此类偏差.
所以应该这样处理:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
return
}
defer res.Body.Close()
// Read/work with body
Notes:个
正如jimB也确认的那样,如果返回非nil
错误,即使响应为非nil
,我们也不必关闭它.在重定向错误的情况下,非nil
响应可以保存上下文和关于随后重定向失败的位置的进一步信息.请参阅以下详细信息:
http.Get()
遵循"大多数时间"的一般概念:如果出现错误,它将返回nil
响应:
return nil, someError
但是,判断client.go
,未导出的方法Client.doFollowingRedirects()
,当前行#427:
if redirectFailed {
// Special case for Go 1 compatibility: return both the response
// and an error if the CheckRedirect function failed.
// See https://golang.org/issue/3795
return resp, urlErr
}
因此,由于向后兼容性问题,如果重定向失败,它可能会同时返回非nil
响应和非nil
错误.
另一方面,如果resp
是nil
,try 拨打resp.Body.Close()
会导致运行时panic .
因此,如果我们想在本例中关闭响应正文,它可能如下所示(只有在resp
不是nil
的情况下才能关闭):
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
if res != nil {
defer res.Body.Close()
// Read/work with body
}
或者:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
if res == nil {
return
}
defer res.Body.Close()
// Read/work with body
http.Response
的doc保证即使没有响应数据,Response.Body
也不会是nil
:
// The http Client and Transport guarantee that Body is always
// non-nil, even on responses without a body or responses with
// a zero-length body.
But如果错误不是nil
,则不必关闭非nil
响应正文.