2017-06-14 2 views
-1

Ich habe versucht, eine Funktion in Go zu erstellen, die versucht, alle Fehlerabfragefunktionen (in der Regel wegen Serialisierungsproblem) erneut zu versuchen.Pass-Funktion als Argument in Go

func retryer(functionA func(interface{}) (interface{}, []error), maxRetry int, waitBetween time.Duration) interface{} { 
    //when no error in functionA, retryer returns whatever functionA returns 
    //when maxRetry is reached, returns nil 
} 

Die Funktionen Ich mag dieses

func GetTopStudent(classId string) ([]Student, []error) { 
    //queries top 10 students for class with classId 
} 

func GetAverageStudentScores(classId string, from time.Time, until time.Time) ([]Pair, []error) { 
    //queries all average score using aggregate, grouping by studentId 
    //Pair behaves like C++ pair<string,string> 
} 

Aber die Ergebnisse sind schaute erneut zu versuchen wollen, ist ein Compiler-Fehler

cannot use GetTopStudent (type func(string) ([]Student, []error)) as type func(interface{}) (interface {}, []error) in argument to retryer 

Ich habe versucht, es ein wenig zu ändern und ich einen weiteren Kompilierungsfehler bekommen

cannot use GetTopStudent (type func(string) ([]Student, []error)) as type func(string) (interface {}, []error) in argument to retryer 

Kann jemand mir helfen, eine allgemeine Funktion zu verursachen, um eine Funktion zu wiederholen, die bei Fehler wiederholt wird?

+2

Die Signaturen der als Parameter übergeben Funktionen muss die Unterschrift der Funktion entsprechen Art des Parameters genau. Sie müssen die übergebenen Funktionen neu schreiben, um 'interface {}' s zu übernehmen und sie auf die entsprechenden Typen innerhalb dieser Funktionen zu übertragen. – xunatai

+0

Auf diese Weise brauche ich für N Funktionen N Wrapper. Ich brauche den allgemeinen Funktions-Wrapper, um den Code wesentlich zu vereinfachen. – Kuzunoha

+1

Ja. Oder Redesign. – Volker

Antwort

1

Ein besserer Weg zur Lösung Ihres Problems wäre die Verwendung von Verschlüssen.

Ändern Sie zum Beispiel die Art der retryer:

func retryer(f func() error, maxRetry int, waitBetween time.Duration) error { 
    // retry and wait logic 
    err := f() 
    // error handling, retry, and wait logic 
    return err 
} 

Jetzt Funktionen aufrufen werden erneut versucht als:

// ... 
classId := "some value" 
// ... 

var st []Student 
var errors []error 
err := retryer(func() error { 
    st, errors = GetTopStudent(classId) 
    // handle errors 
    return nil 
}, numTries, waitTime) 
// use st here