包装的HandleFunc从哪里获取responseWriter并从中请求?

时间:2014-02-24 07:15:19

标签: go

我正在阅读“The Way to Go”一书,虽然我最了解,但我对以下内容感到困难。

作者提到了一种将HandleFunc包装在一个关闭恐慌的闭包中的方法:

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?
    }
}

稍后通过以下方式调用:

http.HandleFunc("/", logPanics(Index))

我理解其中的大部分内容,但想知道w / req在

中是如何使用的
function(w, req)

获得他们的价值观?我是否理解正确,返回语句中的w和req

return func(w http.ResponseWriter, req *http.Request)

完全不同?然后我想知道,w和req如何获得他们的价值观。我希望有人可以对我的问题有所了解,因为我真的想了解发生了什么,而不仅仅是复制和粘贴。

2 个答案:

答案 0 :(得分:3)

当您调用http.HandleFunc(path, function)时,它会导致服务器在收到给定路径的请求时调用function。调用该函数时,*http.Request描述来自客户端的请求,http.ResponseWriter可用于将响应写回客户端。

在以下电话中:

http.HandleFunc("/", logPanics(Index))

正在注册的处理函数是logPanics返回的函数。收到/的请求后,将调用该函数。该函数反过来调用您的Index函数并捕获任何恐慌。

答案 1 :(得分:3)

  

我是否正确理解,返回语句中的w和req   return func(w http.ResponseWriter, req *http.Request)   是完全不同的?

不,完全没有,这些都是一样的!一旦删除延迟和 将闭包分配给变量会变得更清晰:

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
}

没有这个代码什么也不做,但很容易看出发生了什么:1)f是一个具有正确签名的函数(采用ResponseWriter和Request)。 2)它所做的就是调用传递给logPanics的函数并调用它的参数。 3)返回此函数f

相关问题