2017-03-15 5 views
7

Ich bin neu zu Golang und ich habe gelegentlich einige Code gesehen, der eine Funktion innerhalb eines Funktionstyps umschließt. In http-Paket haben wir dies auch:Was bringt es, eine Funktion in einen Funktionstyp zu integrieren?

type HandlerFunc func(ResponseWriter, *Request) 

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { 
    f(w, r) 
} 

Ich bin gespannt, den Grund zu kennen. Wenn wir einen Typ haben wollen, der eine Methode verfügbar macht, warum erstellen wir dann keinen Strukturtyp und fügen ihm die Methode hinzu?

Antwort

5

Zwei Hauptgründe:

  1. Convenience, wenn Funktionen als Argumente empfangen:

    type LongFuncSig func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error) 
    
    func DoSomething(fn LongFuncSig) { ... } 
    func DoSomethingElse(fn LongFuncSig) { ... } 
    func DoYetAnotherThing(fn LongFuncSig) { ... } 
    

    ist viel besser lesbar und weniger fehleranfällig als:

    func DoSomething(fn func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)) { ... } 
    func DoSomethingElse(fn func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)) { ... } 
    func DoYetAnotherThing(fn func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)) { ... } 
    
  2. Wenn Sie möchten Methoden an den Typ anhängen. In Ihrem Beispiel hat http.HandlerFunc eine angehängte Methode, ServeHTTP. Dies bewirkt, dass die Funktion die http.Handler Schnittstelle erfüllt. Es ist nur möglich, Methoden an benannte Typen anzuhängen.

    Und Ihre weitere Frage zu beantworten:

    Wenn wir einen Typ haben wollen, das ein Verfahren aussetzt, warum wir nicht eine Strukturtyp und fügen Sie die Methode, um sie zu erstellen?

    Weil es keinen Grund gibt, das zu tun. Die Standardbibliothek könnte hat Ihren Vorschlag mit nehmen gewählt:

    type HandlerFunc struct { 
        Func: func(ResponseWriter, *Request) 
    } 
    

    Aber das ist weit ausführliche und schwieriger zu bedienen und zu lesen. Zu verwenden, dass, würden Sie dann verlangen:

    http.HandlerFunc{Func: fn} 
    

    statt der viel einfacher:

    http.HandlerFunc(fn) 
    

    So gibt es keinen Grund, um unnötige Komplexität hinzuzufügen.

+0

Danke. Meine Frage war in der Tat, was Sie in Punkt 2 geantwortet haben. –

Verwandte Themen