2009-11-21 10 views
10

Ich möchte wissen, was hier passiert.Funktion Implementierung Schnittstelle

Es ist die Schnittstelle für einen http-Handler:

type Handler interface { 
    ServeHTTP(*Conn, *Request) 
} 

Diese Implementierung Ich glaube, ich verstehe.

Aus meiner Sicht ist es, dass der Typ "Counter" die Schnittstelle implementiert, da es eine Methode hat, die die erforderliche Signatur hat. So weit, ist es gut. Dann ist dieses Beispiel gegeben:

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

Kann jemand näher erläutern, warum oder wie diese verschiedenen Funktionen zusammenpassen?

Antwort

12

Dies:

type Handler interface { 
    ServeHTTP(*Conn, *Request) 
} 

sagt, dass jede Art, die die Handler Schnittstelle erfüllt eine ServeHTTP Methode haben muss. Das obige wäre in der Verpackung http.

Dies setzt eine Methode auf den Counter-Typ, der ServeHTTP entspricht. Dies ist ein Beispiel, das von dem folgenden getrennt ist.

Von meinem Verständnis ist es, dass der Typ „Zähler“ implementiert die Schnittstelle, da es eine Methode, die die erforderliche Signatur hat.

Das stimmt.

Die folgende Funktion selbst wird nicht als Handler arbeiten:

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"); 
} 

Der Rest dieses Zeug nur die oben passend, so dass es eine Handler sein kann.

Im Folgenden wird eine HandlerFunc ist eine Funktion, die zwei Argumente, Zeiger auf Conn und Zeiger auf Request und gibt nichts. Mit anderen Worten, jede Funktion, die diese Argumente übernimmt und nichts zurückgibt, kann eine HandlerFunc sein.

// Now we define a type to implement ServeHTTP: 
type HandlerFunc func(*Conn, *Request) 

Hier ServeHTTP ist ein Verfahren der Art hinzugefügt HandlerFunc:

func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) { 
    f(c, req) // the receiver's a func; call it 
} 

Alles, was es tut, ist angesichts der Funktion selbst (f) mit den Argumenten zu nennen.

// Convert function to attach method, implement the interface: 
var Handle404 = HandlerFunc(notFound); 

In der obigen Zeile, für die Schnittstelle für Handler durch künstliches Erzeugen einer Typ-Instanz aus der Funktion selbst und macht die Funktion in das ServeHTTP Verfahren für die Instanz in akzeptabel finagled notFound wurde. Jetzt kann Handle404 mit der Handler Schnittstelle verwendet werden. Es ist im Grunde eine Art Trick.

+0

Ok Ich denke, ich verstehe es jetzt, die Sache, die mich stolperte, war die Umwandlung von notFound in HandlerFunc. Nach dem erneuten Lesen des Konvertierungsabschnitts von effective go ist es klarer, wie dies auch für Funktionen gelten kann. http://golang.org/doc/effective_go.html#conversions – mbarkhau

1

Was genau verstehst du nicht über die zweite Hälfte? Es ist das gleiche Muster wie oben. Anstatt den Counter-Typ als int zu definieren, definieren sie eine Funktion namens notFound. Sie erstellen dann einen Funktionstyp namens HandlerFunc, der zwei Parameter, eine Verbindung und eine Anforderung, enthält. Sie erstellen dann eine neue Methode namens ServeHTTP, die an den HandlerFunc-Typ gebunden wird. Handle404 ist einfach eine Instanz dieser Klasse, die die notFound-Funktion verwendet.

+2

Ja, es ist typische funktionale Programmierung höherer Ordnung. Es kann verwirrend sein, wenn Sie es das erste Mal sehen und sich durch die Typen arbeiten. – Suppressingfire

Verwandte Themen