This is a creation in Article, where the information may have evolved or changed.
Because almost anything can be used, almost anything can satisfy a certain interface. A demonstration example is the Handler interface defined by the HTTP package. Any object implements the handler to serve HTTP requests.
type Handler interface { ServeHTTP(*Conn, *Request) }
The responsewriter itself is an interface that provides some accessible ways to return a customer's request. These methods include the standard Write method. So http. Responsewriter can be used in IO. Writer can use the place. Request is a structure that contains a parsed representation of a customer request.
For brevity, we ignore POST and assume that all HTTP requests are GET, and that this simplification does not affect the user's settings. The following comprehensive rollup implements a count of page visits.
// Simple counter server. type Counter struct { n int } func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) { ctr.n++ fmt.Fprintf(c, "counter = %d\n", ctr.n) }
(Note how fprintf prints to http.) Responsewriter). As a reference, here's how to add a server to a node on a URL tree.
import "http" ... ctr := new(Counter) http.Handle("/counter", ctr)
But why do we use Counter as a structure? An integer is available. (The recipient needs to be a pointer to bring the increment back to the caller).
// Simpler counter server. type Counter int func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) { *ctr++ fmt.Fprintf(c, "counter = %d\n", *ctr) }
How do you tell your program to update certain internal states when a page is accessed? Put a channel on the page.
// A channel that sends a notification on each visit. // (Probably want the channel to be buffered.) type Chan chan *http.Request func (ch Chan) ServeHTTP(c *http.Conn, req *http.Request) { ch <- req fmt.Fprint(c, "notification sent") }
Finally, let's show the parameters in/args when starting the server. Writing a function for printing parameters is easy:
func ArgServer() { for i, s := range os.Args { fmt.Println(s) } }
How do you turn it into an HTTP server? We can ignore the value of Argserver as a method of a certain type and have a cleaner approach. Since we can define a method for any type of non-pointer and interface, we can write a method to the function. The following code is in the HTTP package:
// The HandlerFunc type is an adapter to allow the use of // ordinary functions as HTTP handlers. If f is a function // with the appropriate signature, HandlerFunc(f) is a // Handler object that calls f. type HandlerFunc func(*Conn, *Request) // ServeHTTP calls f(c, req). func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) { f(c, req) }
Handlerfunc is a type with a servehttp method, so the values of this class can serve HTTP requests. Let's take a look at the implementation of this method: the recipient is a function, F, method call F. It looks weird, but with, for example, the recipient is the channel, and the method is sent to this channel, nothing different.
To turn Argserver into an HTTP server, we first change to the correct signature:
// Argument server. func ArgServer(c *http.Conn, req *http.Request) { for i, s := range os.Args { fmt.Fprintln(c, s) } }
Argserver now has the same signature as Handlerfunc and can be turned into this class using its method, just as we have Sequence to Intarray to use Intarray.sort. The Setup code is brief:
http.Handle("/args", http.HandlerFunc(ArgServer))
When someone accesses the/args page, the person who handles the page has value Argserver and type Handlerfunc. The HTTP server initiates this type of Servehttp method, using Argserver as the recipient, which in turn calls Argserver (by starting Handlerfunc.servehttp F (w, req). ) parameters are displayed.
In this section we create an HTTP server from a struct, an integer, a channel, and a function, and all depends on the interface is a set of methods that can be defined on (almost) any type.