为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
德玛西亚99 2021-11-08 18:58:08
在下面的代码中是否还需要在错误情况下关闭响应体:res, err := http.Get(url)if err != nil {    log.Printf("Error: %s\n", err)}defer res.Body.Close()
查看完整描述

1 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

一般概念是,当一个函数(或方法)有多个返回值时,一个是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 respisnil会导致运行时恐慌。


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


// 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响应主体。


查看完整回答
反对 回复 2021-11-08
  • 1 回答
  • 0 关注
  • 233 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信