一尘不染

功能实现界面

go

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

有一个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++;
}

根据我的理解,“计数器”类型实现了接口,因为它具有一种具有所需签名的方法。到目前为止,一切都很好。然后给出这个例子:

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);

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


阅读 263

收藏
2020-07-02

共1个答案

一尘不染

这个:

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类型上。这是一个与以下示例分开的示例。

根据我的理解,“计数器”类型实现了接口,因为它具有一种具有所需签名的方法。

那就对了。

以下功能本身不能用作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

在下面的代码中,a HandlerFunc是一个函数,它接受两个参数: 指向Conn_和的
_指针Request
,并且不返回任何内容。换句话说,任何接受这些参数且不返回任何值的函数都可以是HandlerFunc

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

ServeHTTP是添加到类型的方法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接口可接受。现在可以与该接口一起使用。这基本上是一种技巧。Handler``ServeHTTP``Handle404``Handler

2020-07-02