如果在调用http.Get(url)时出现错误,是否需要关闭响应对象?
Do we need to close the response object if an error occurs while calling http.Get(url)?
在下面的代码中是否也需要在错误情况下关闭响应体:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
defer res.Body.Close()
一般概念是,当一个函数(或方法)有多个 return 值时,一个是 error
,应该首先检查错误,只有在错误是 nil
时才继续.如果存在 error
,函数应该 return 将其他(非错误)值设为零。如果函数的行为不同,则应记录在案。 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
备注:
正如 JimB 也确认的那样,如果 return 编辑了非 nil
错误,即使响应是非 nil
,我们也不必关闭它。在重定向错误的情况下,非 nil
响应可能包含上下文和有关重定向失败的位置的更多信息。请参阅以下详细信息:
http.Get()
遵循一般概念 "most of the time":如果出现错误,它 returns 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
}
因此,由于向后兼容性问题,如果重定向失败,它可能会同时 return 非 nil
响应和非 nil
错误。
另一方面,如果 resp
为 nil
,则尝试调用 resp.Body.Close()
将导致 运行 次恐慌。
所以如果我们想在这种情况下关闭响应主体,它可能看起来像这样(只有 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
的文档保证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.
但是如果错误不是nil
,你不必关闭非nil
响应体。
在下面的代码中是否也需要在错误情况下关闭响应体:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
defer res.Body.Close()
一般概念是,当一个函数(或方法)有多个 return 值时,一个是 error
,应该首先检查错误,只有在错误是 nil
时才继续.如果存在 error
,函数应该 return 将其他(非错误)值设为零。如果函数的行为不同,则应记录在案。 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
备注:
正如 JimB 也确认的那样,如果 return 编辑了非 nil
错误,即使响应是非 nil
,我们也不必关闭它。在重定向错误的情况下,非 nil
响应可能包含上下文和有关重定向失败的位置的更多信息。请参阅以下详细信息:
http.Get()
遵循一般概念 "most of the time":如果出现错误,它 returns 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
}
因此,由于向后兼容性问题,如果重定向失败,它可能会同时 return 非 nil
响应和非 nil
错误。
另一方面,如果 resp
为 nil
,则尝试调用 resp.Body.Close()
将导致 运行 次恐慌。
所以如果我们想在这种情况下关闭响应主体,它可能看起来像这样(只有 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
的文档保证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.
但是如果错误不是nil
,你不必关闭非nil
响应体。