英文:
Where does a wrapped HandleFunc get responseWriter and request from?
问题
我正在阅读《The Way to Go》这本书,虽然我理解大部分内容,但以下部分让我有些困惑。
作者提到了一种将 HandleFunc 包装在闭包中以处理 panic 的方法,代码如下:
func Index(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprint(w, "<h2>Index</h2>")
}
func logPanics(function HandleFunc) HandleFunc {
return func(w http.ResponseWriter, req *http.Request) {
defer func() {
if err := recover(); err != nil {
log.Printf("[%v] caught panic: %v", req.RemoteAddr, err)
}
}()
function(w, req) // w 和 req 是从哪里来的?
}
}
然后通过以下方式调用:
http.HandleFunc("/", logPanics(Index))
我理解大部分内容,但是想知道在
function(w, req)
中的 w 和 req 是如何获取它们的值的?我是否正确理解,在返回语句中的 w 和 req
return func(w http.ResponseWriter, req *http.Request)
是完全不同的?然后我想知道,w 和 req 是如何获取它们的值的。希望有人能解答我的问题,因为我真的想理解发生了什么,而不仅仅是复制粘贴。
英文:
I'm reading "The Way to Go" book and while I understand most, I'm having a difficulty with the following.
The author mentions a way to wrap a HandleFunc in a closure that takes care of panics like so:
func Index(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprint(w, "<h2>Index</h2>")
}
func logPanics(function HandleFunc) HandleFunc {
return func(w http.ResponseWriter, req *http.Request) {
defer func() {
if err := recover(); err != nil {
log.Printf("[%v] caught panic: %v", req.RemoteAddr, err)
}
}()
function(w, req) // Where do w and req come from?
}
}
Later on this is invoked via:
http.HandleFunc("/", logPanics(Index))
I understand most of it, but wonder how w and req used in
function(w, req)
get their values? Do I understand correctly, that the w and req in the return statement
return func(w http.ResponseWriter, req *http.Request)
are completely different? Then I wonder, how do w and req get their values. I hope somebody can shed some light on my question as I really want to understand what's going on instead of just copying and pasting.
答案1
得分: 3
当你调用http.HandleFunc(path, function)
时,它会导致服务器在接收到给定路径的请求时调用function
。该函数会使用描述来自客户端的请求的*http.Request
和一个可用于向客户端写回响应的http.ResponseWriter
来调用。
在下面的调用中:
http.HandleFunc("/", logPanics(Index))
被注册的处理函数是由logPanics
返回的函数。当收到对/
的请求时,将调用该函数。该函数反过来调用你的Index
函数并捕获任何panic。
英文:
When you call http.HandleFunc(path, function)
, it causes the server to invoke function
when a request is received for the given path. The function is called with a *http.Request
describing the request from the client and a http.ResponseWriter
that can be used to write a response back to the client.
In the following call:
http.HandleFunc("/", logPanics(Index))
The handler function being registered is the function returned by logPanics
. When a request for /
is received, that function will be called. That function in turn calls your Index
function and traps any panics.
答案2
得分: 3
我理解得对吗,return语句中的w和req,即return func(w http.ResponseWriter, req *http.Request)
,完全不同吗?
不,完全不是这样,它们是相同的!一旦你删除了defer并将闭包赋值给一个变量,情况就会变得更清晰:
func logPanics(function HandleFunc) HandleFunc {
f := func(w http.ResponseWriter, req *http.Request) {
function(w, req) // w和req是从哪里来的?
}
return f
}
这段代码实际上什么都没做,但很容易看出其中的过程:1)f
是一个具有正确签名(接受ResponseWriter和Request)的函数。2)它所做的就是使用传递给logPanics
的函数和调用它的参数来调用该函数。3)这个函数f
被返回。
英文:
> Do I understand correctly, that the w and req in the return statement
> return func(w http.ResponseWriter, req *http.Request)
> are completely different?
No, not at all, these are the same! Once you delete the defer and
assign the closure to a variable it becomes a bit clearer:
func logPanics(function HandleFunc) HandleFunc {
f := func(w http.ResponseWriter, req *http.Request) {
function(w, req) // Where do w and req come from?
}
return f
}
No this code does nothing at all but it is easy to see what goes on: 1) f
is a function with the proper signature (taking a ResponseWriter and a Request). 2) All it does is call the function passed to logPanics
with the argument it was called. 3) This function f
is returned.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论