Go 功能实现接口

Go 功能实现接口,go,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

我想知道这里发生了什么

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

有人能详细解释一下为什么或者如何将这些不同的功能组合在一起吗?

关于下半部分,你到底不明白什么?这是和上面一样的图案。它们没有将计数器类型定义为int,而是定义了一个名为notFound的函数。然后,他们创建一个名为HandlerFunc的函数类型,该函数接受两个参数,一个连接和一个请求。然后,他们创建一个名为ServeHTTP的新方法,该方法绑定到HandlerFunc类型。Handle404只是这个类的一个实例,它使用notFound函数。

这个:

type Handler interface {
    ServeHTTP(*Conn, *Request)
}
表示满足
处理程序
接口的任何类型都必须具有
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”实现 接口,因为它有一个 具有所需的签名

以下函数本身不能作为
处理程序

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");
}
这些东西的其余部分正好适合上面的内容,这样它就可以成为一个
处理程序

在下文中,
HandlerFunc
是一个函数,它接受两个参数,即指向
Conn
的指针和指向
请求的指针,并且不返回任何内容。换句话说,任何接受这些参数但不返回任何内容的函数都可以是
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
接口一起使用。这基本上是一种技巧。

是的,这是典型的高阶函数编程。当你第一次看到它的时候,你可能会觉得很困惑,然后用你的方式处理这些类型。好吧,我想我现在明白了,让我大吃一惊的是把notFound转换成HandlerFunc。在重新阅读了有效go的转换部分后,更清楚地知道如何将其应用于函数。