I want to know what is happening here.
There is the interface for a http handler:
type Handler interface {
ServeHTTP(*Conn, *Request)
}
This implementation I think I understand.
type Counter int
func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
fmt.Fprintf(c, "counter = %d\n", ctr);
ctr++;
}
From my understanding it is that the type "Counter" implements the interface since it has a method that has the required signature. So far so good. Then this example is given:
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 i开发者_开发百科t
}
// Convert function to attach method, implement the interface:
var Handle404 = HandlerFunc(notFound);
Can somebody elaborate on why or how these various functions fit together?
This:
type Handler interface {
ServeHTTP(*Conn, *Request)
}
says that any type which satisfies the Handler
interface must have a ServeHTTP
method. The above would be inside the package http
.
type Counter int
func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
fmt.Fprintf(c, "counter = %d\n", ctr);
ctr++;
}
This puts a method on the Counter type which corresponds to ServeHTTP. This is an example which is separate from the following.
From my understanding it is that the type "Counter" implements the interface since it has a method that has the required signature.
That's right.
The following function by itself won't work as a 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");
}
The rest of this stuff is just fitting the above so that it can be a Handler
.
In the following, a HandlerFunc
is a function which takes two arguments, pointer to Conn
and pointer to Request
, and returns nothing. In other words, any function which takes these arguments and returns nothing can be a HandlerFunc
.
// Now we define a type to implement ServeHTTP:
type HandlerFunc func(*Conn, *Request)
Here ServeHTTP
is a method added to the type HandlerFunc
:
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
f(c, req) // the receiver's a func; call it
}
All it does is to call the function itself (f
) with the arguments given.
// Convert function to attach method, implement the interface:
var Handle404 = HandlerFunc(notFound);
In the above line, notFound
has been finagled into being acceptable for the interface for Handler
by artificially creating a type instance out of the function itself and making the function into the ServeHTTP
method for the instance. Now Handle404
can be used with the Handler
interface. It's basically a kind of trick.
What exactly don't you understand about the second half? It's the same pattern as above. Instead of defining the Counter type as an int, they define a function called notFound. They then create a type of function called HandlerFunc that takes two parameters, a connection and a request. they then create a new method called ServeHTTP, that gets bound to the HandlerFunc type. Handle404 is simply an instance of this class that uses the notFound function.
精彩评论