上一小节对处理器进行了介绍,那么什么是处理器函数呢?处理器函数实际上就是与处理器拥有相同行为的函数:这些函数与ServeHTTP方法拥有相同的签名,也就是说,它们接受ResponseWriter和指向Request结构的指针作为参数。代码清单3-8展示了如何在服务器中使用处理器函数。

代码清单3-8 使用处理器函数处理请求

package main

import (
    "fmt"
    "net/http"
)

func hello (w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

func world (w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "World!")
}

func main() {

    server := http.Server {
        Addr: "127.0.0.1:8080",
    }

    http.Handle("/hello", hello)
    http.Handle("/world", world)

    server.ListenAndServe()
}

处理器函数的实现原理是这样的:Go语言拥有一种HandlerFunc函数类型,它可以把一个带有正确签名的函数f转换成一个带有方法fHandler。比如说,对下面这个hello函数来说:

func hello(w http.ResponseWriter, r *http.Request) {      
    fmt.Fprintf(w, "Hello!")
}

程序只需要执行以下代码:

helloHandler := HandlerFunc(hello)

就可以把helloHandler设置成一个Handler。如果你对此感到疑惑,那么不妨回顾一下之前展示过的接受处理器的服务器代码

package main

import (
    "fmt"
    "net/http"
)

type HelloHandler struct{}

func (h *HelloHandler) ServeHTTP (w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

type WorldHandler struct{}

func (h *WorldHandler) ServeHTTP (w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "World!")
}

func main() {
    hello := HelloHandler{}
    world := WorldHandler{}

    server := http.Server {
        Addr: "127.0.0.1:8080",
    }

    http.Handle("/hello", &hello)
    http.Handle("/world", &world)

    server.ListenAndServe()
}

这个程序使用了以下这行代码来绑定URL地址/hellohello函数:

http.Handle("/hello", &hello)

这行代码向我们展示了Handle函数将一个处理器绑定至URL的具体方法。此外,在接受处理器函数的代码清单3-8中,HandleFunc函数会将hello函数转换成一个Handler,并将它与DefaultServeMux进行绑定,以此来简化创建并绑定Handler的工作。换句话说,处理器函数只不过是创建处理器的一种便利的方法而已。代码清单3-9展示了http.HandleFunc函数的具体定义。

代码清单3-9 http.HandleFunc函数的源代码

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}
//而下面是ServeMux.HandleFunc方法的定义:
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter,     *Request)) {    
    mux.Handle(pattern, HandlerFunc(handler))
}

注意这个方法是如何使用HandlerFunc函数将传入的handler函数转换成真正的处理器的。

虽然处理器函数能够完成跟处理器一样的工作,并且使用处理器函数的代码比使用处理器的代码更为整洁,但是处理器函数并不能完全代替处理器。这是因为在某些情况下,代码可能已经包含了某个接口或者某种类型,这时我们只需要为它们添加ServeHTTP方法就可以将它们转变为处理器了,并且这种转变也有助于构建出更为模块化的Web应用。

results matching ""

    No results matching ""