17

我想知道这里发生了什么。

有一个 http 处理程序的接口:

type Handler interface {
    ServeHTTP(*Conn, *Request)
}

这个实现我想我明白了。

type Counter int

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
    fmt.Fprintf(c, "counter = %d\n", ctr);
    ctr++;
}

据我了解,“Counter”类型实现了接口,因为它有一个具有所需签名的方法。到现在为止还挺好。然后给出这个例子:

func notFound(c *Conn, req *Request) {
    c.SetHeader("Content-Type", "text/plain;", "charset=utf-8");
    c.WriteHeader(StatusNotFound);
    c.WriteString("404 page not found\n");
}

// Now we define a type to implement ServeHTTP:
type HandlerFunc func(*Conn, *Request)
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req) // the receiver's a func; call it
}
// Convert function to attach method, implement the interface:
var Handle404 = HandlerFunc(notFound);

有人可以详细说明为什么或如何将这些不同的功能组合在一起吗?

4

2 回答 2

23

这:

type Handler interface {
    ServeHTTP(*Conn, *Request)
}

表示任何满足Handler接口的类型都必须有ServeHTTP方法。以上将在包内http

type Counter int

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
    fmt.Fprintf(c, "counter = %d\n", ctr);
    ctr++;
}

这在对应于 ServeHTTP 的 Counter 类型上放置了一个方法。这是一个与以下内容不同的示例。

据我了解,“Counter”类型实现了接口,因为它有一个具有所需签名的方法。

这是正确的。

以下函数本身不能用作Handler

func notFound(c *Conn, req *Request) {
    c.SetHeader("Content-Type", "text/plain;", "charset=utf-8");
    c.WriteHeader(StatusNotFound);
    c.WriteString("404 page not found\n");
}

这些东西的其余部分只是适合上面的,所以它可以是Handler.

在下文中,aHandlerFunc是一个函数,它接受两个参数,指向的指针Conn指向的指针Request,并且不返回任何内容。换句话说,任何接受这些参数但不返回任何内容的函数都可以是HandlerFunc.

// Now we define a type to implement ServeHTTP:
type HandlerFunc func(*Conn, *Request)

ServeHTTP是添加到 type 的方法HandlerFunc

func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req) // the receiver's a func; call it
}

它所做的只是f使用给定的参数调用函数本身()。

// Convert function to attach method, implement the interface:
var Handle404 = HandlerFunc(notFound);

在上面的行中,通过人为地从函数本身创建一个类型实例并将函数放入实例的方法中,notFound已经被接口接受了。现在可以配合界面使用了。这基本上是一种技巧。HandlerServeHTTPHandle404Handler

于 2009-11-21T06:38:03.267 回答
0

下半场你到底有什么不明白的?它与上面的模式相同。他们没有将 Counter 类型定义为 int,而是定义了一个名为 notFound 的函数。然后,他们创建了一种名为 HandlerFunc 的函数,它接受两个参数,一个连接和一个请求。然后他们创建了一个名为 ServeHTTP 的新方法,该方法绑定到 HandlerFunc 类型。Handle404 只是使用 notFound 函数的此类的一个实例。

于 2009-11-21T02:08:26.493 回答