您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如果在调用http.Get(url)时发生错误,我们是否需要关闭响应对象?

如果在调用http.Get(url)时发生错误,我们是否需要关闭响应对象?

一般概念是,当一个函数(或方法)具有多个返回值(一个为an)时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

正如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.Body.Close()if respis nil将导致运行时恐慌。

因此,如果我们想在这种情况下关闭响应主体,它可能看起来像这样(如果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响应主体。

其他 2022/1/1 18:17:35 有552人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶