Go语言 何时不关闭响应体

jdzmm42g  于 2023-04-03  发布在  Go
关注(0)|答案(2)|浏览(135)

golang要求在用户代码中关闭http请求的响应体,以释放资源:

client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
    return nil, err
}
defer resp.Body.Close()

我的问题是:为什么是这样的设计?有没有不关闭的情况是有益的?为什么标准库不为用户关闭client.Do(req)内的连接?
我这么问是因为这是我经常看到的一个代码审查问题。

kt06eoxx

kt06eoxx1#

您从服务器接收的内容没有大小限制。您可能正在下载一个非常大的文件。这就是为什么响应包含一个阅读器:这样你就能得到回应了
由于可以流式传输响应,因此必须在完成后或对其余结果不感兴趣时关闭流。当您关闭流时,服务器将知道您不再对接收流的其余部分感兴趣,并且它将有机会清理。

oyt4ldly

oyt4ldly2#

关闭阅读器的原因已经在@Burak塞尔达尔的回答中解释过了。
有没有不关闭的情况是有益的?。为什么标准库不关闭客户端内的连接。Do(req)for the user?
如果您需要创建一个自定义客户端来 Package Do(),同时返回一个未关闭的读取器,这可能是有益的。
举个简单的例子:

func main() {
    myCustomClient := CustomClient{
        client: http.Client{},
    }
    req,_ := http.NewRequest("GET", "example.com", nil)
    res, _ := myCustomClient.Do(req)
    defer res.Body.Close()
    // (2) so you can read from it here

}

type CustomClient struct {
    client http.Client
}

func (c CustomClient)Do(req *http.Request)(*http.Response, error){
    // you may add some custom logic here, such as adding some headers
    // (1) and return the response without closing it 
    return c.client.Do(req)
}

相关问题