一个包装的HandleFunc函数从哪里获取responseWriter和request?

huangapple go评论65阅读模式
英文:

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(&quot;Content-Type&quot;, &quot;text/html&quot;)
    fmt.Fprint(w, &quot;&lt;h2&gt;Index&lt;/h2&gt;&quot;)
}

func logPanics(function HandleFunc) HandleFunc {
    return func(w http.ResponseWriter, req *http.Request) {
        defer func() {
            if err := recover(); err != nil {
              log.Printf(&quot;[%v] caught panic: %v&quot;, req.RemoteAddr, err)
            }
        }()
        function(w, req) // Where do w and req come from?
    }
}

Later on this is invoked via:

http.HandleFunc(&quot;/&quot;, 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(&quot;/&quot;, 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.

huangapple
  • 本文由 发表于 2014年2月24日 15:15:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/21981194.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定