我正在阅读“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如何获得他们的价值观。我希望有人可以对我的问题有所了解,因为我真的想了解发生了什么,而不仅仅是复制和粘贴。
答案 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
。