功能实现界面

时间:2009-11-21 01:44:14

标签: 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++;
}

根据我的理解,“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);

有人可以详细说明这些不同功能为何或如何结合在一起?

2 个答案:

答案 0 :(得分:13)

此:

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++;
}

这将一个方法放在Counter类型上,该方法对应于ServeHTTP。这是一个与以下内容分开的例子。

  

从我的理解是这个   类型“计数器”实现   接口,因为它有一个方法   有必要的签名。

没错。

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

在下文中,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界面一起使用。这基本上是一种技巧。

答案 1 :(得分:1)

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