我想知道这里发生了什么。
有一个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);
有人可以详细说明为什么这些功能或如何将它们组合在一起吗?
这个:
说任何满足Handler接口的类型都必须有一个ServeHTTP方法。以上将在包装内http。
Handler
ServeHTTP
http
这会将方法放在对应于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。
HandlerFunc
Conn
Request
// 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用给定的参数调用函数本身()。
f
// Convert function to attach method, implement the interface: var Handle404 = HandlerFunc(notFound);
在上面的代码中,通过在函数本身中人为地创建类型实例并将该函数制成实例的方法,最终使其对notFound接口可接受。现在可以与该接口一起使用。这基本上是一种技巧。Handler``ServeHTTP``Handle404``Handler
notFound
Handler``ServeHTTP``Handle404``Handler