我有一些使用
net/http
模块编写的 web 服务器处理程序,每个处理程序中都有 defer req.Body.Close()
语句。请问这段代码应该放在哪个位置?是在函数末尾还是开头无所谓呢?net/http
模块编写的 web 服务器处理程序,每个处理程序中都有 defer req.Body.Close()
语句。请问这段代码应该放在哪个位置?是在函数末尾还是开头无所谓呢?在处理程序中,请求体不需要被关闭。来自http.Request
文档。
// The Server will close the request body. The ServeHTTP
// Handler does not need to.
net/http
在2ede818中澄清,net/http
声明:
对于服务器请求,请求体(Request Body)始终非空,但当没有请求体时将立即返回EOF。 服务器将关闭请求体,ServeHTTP处理程序不需要这样做。
defer req.Body.Close()
已经成为了惯例。如果请求失败(返回非 nil 的错误),则没有 Body 可以关闭,无论是通过延迟(defer
)方式还是直接方式。
您必须在可能涉及到的所有代码路径上关闭 Body(如果存在)。
在处理 Body(或至少处理部分 Body)之前,您可能不想关闭它。
"在函数开头": 这完全是错误的,因为 Body 可能为空(事实1)。
"在函数结尾": 完全错误,因为A) 如果您错过了一个离开函数的代码路径(事实2),那么它就会变得很危险。B) 即使您在函数结束时加上 defer Bod.Close()
,也完全没有意义,与直接通过 Body.Close()
关闭它相比,延迟关闭毫无用处。
http.NewRequest("some method", "some path", nil)
) - TwiN如文档所述,无需在客户端和服务器端都显式关闭它。
// 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.
defer req.Body.Close()
放在最后,您就不需要使用defer
关键字,但是您会冒着您或任何未来的程序员意外添加代码从而提前从函数返回的风险,那么req.Body.Close()
就不会运行。 - noshttp.Handler
在服务器端处理传入请求的情况,还是在客户端向其他服务器发出传出请求的情况? - icza