英文:
Where to put "defer req.Body.Close()"?
问题
我在网络服务器端有一些使用net/http
处理程序,在每个处理程序中都有defer req.Body.Close()
。
正确的放置位置是什么?我应该将其放在函数的末尾,还是完全不重要,可以将其放在开头?
英文:
I have net/http
handlers that have defer req.Body.Close()
in each on web server side.
What is the correct place to put this in? Should I put it in the end of the function or does it matter at all, and I can put it in the beginning?
答案1
得分: 84
请求体在处理程序中不需要关闭。根据http.Request
文档:
// 服务器将关闭请求体。ServeHTTP处理程序不需要关闭。
英文:
A request body does not need to be closed in the handler. From the http.Request
documentation
// The Server will close the request body. The ServeHTTP
// Handler does not need to.
答案2
得分: 11
net/http
服务器请求
根据 2ede818 的说明,net/http
模块中指出:
<blockquote>
对于服务器请求,请求体(Request Body)始终不为 nil,但当没有请求体时,将立即返回 EOF。
<strong>服务器会关闭请求体,ServeHTTP 处理程序不需要关闭请求体。</strong>
</blockquote>
英文:
net/http
Server requests
Clarified at 2ede818, net/http
states that:
<blockquote>
For server requests, the Request Body is always non-nil but will return EOF immediately when no body is present.
<strong>The Server will close the request body. The ServeHTTP Handler does not need to.</strong>
</blockquote>
2ede818: https://github.com/golang/go/commit/2ede818ae0761fc57dc1b52b4c8673933a3ff3fa "commit 2ede818ae0761fc57dc1b52b4c8673933a3ff3fa"
答案3
得分: 9
这是正确的位置放置它吗?我应该将它放在函数的末尾还是完全无关紧要,我可以将它放在开头?
都不是。两者都是非常错误的。
defer req.Body.Close()
已经成为一种习惯。
首先是一些硬性事实:
-
如果请求失败(返回非空错误),就没有要关闭的 Body,无论是延迟关闭还是直接关闭。
-
你必须在可能的所有代码路径上关闭 Body(如果存在)。
-
在处理请求体之前(或至少部分处理之前),你可能不想关闭 Body。
回到你问题中的选项:
-
"在函数的开头":完全错误,因为 Body 可能为 nil(事实1)。
-
"在函数的末尾":完全错误,因为 A)这是危险的,因为你可能会错过一个离开函数的代码路径(事实2),并且 B)即使你在所有函数结束(即返回)处都使用
defer Bod.Close()
,将其延迟关闭而不是通过Body.Close()
直接关闭是完全无用的。
唯一明智的延迟关闭请求体的方式是,在确定 Body 非空(即请求未返回错误)之后,立即进行一次关闭。
英文:
> What is the correct place to put this in? Should I put it in the end of the function or does it matter at all, and I can put it in the beginning?
Neither nor. Both are terribly wrong.
The defer req.Body.Close()
has become cult.
Hard facts first:
-
If the request failed (non nil error returned) there is no Body to close, neither in a defered way nor a direct way.
-
You must close the Body (if present) on all code paths you might take.
-
You probably do not want to close the Body before having processed it (or at least parts of it).
Back to the options in your question:
-
"at the beginning [of the function]": Totally wrong as Body might be nil (fact 1).
-
"at the end [of the function]": Totally wrong because of A) it is dangerous as you might miss a code path leaving your function (fact 2) and B) even if you equip all your function ends (i.e. returns) with
defer Bod.Close()
it is totally useless to defer it instead of simply closing it viaBody.Close()
.
The only sensible way of defered closing the request body is once, right after having established that Body is non-nil what means the request did not return an error.
答案4
得分: 5
根据文档中的说明,在客户端和服务器端都不需要显式关闭它。
// Body 是请求的主体。
//
// 对于客户端请求,nil 的 body 表示请求没有主体,比如 GET 请求。HTTP 客户端的 Transport 负责调用 Close 方法。
//
// 对于服务器请求,Request Body 总是非 nil 的,但当没有主体时会立即返回 EOF。服务器会关闭请求主体。ServeHTTP 处理程序不需要关闭它。
英文:
As mentioned in the documentation, no need to explicit close it both in client and server side.
// Body is the request's body.
//
// For client requests, a nil body means the request has no
// body, such as a GET request. The HTTP Client's Transport
// is responsible for calling the Close method.
//
// For server requests, the Request Body is always non-nil
// but will return EOF immediately when no body is present.
// The Server will close the request body. The ServeHTTP
// Handler does not need to.
答案5
得分: 2
根据Go的文档,在你完成使用后,需要自己关闭请求体。
通常我会在检查请求是否有错误的代码行后面加上defer语句。
英文:
According to the Go documentation it is up to you to close the body once you are done with it.
I usually put the defer line right after the line where I check the request for errors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论