2017-06-14 46 views
-1

我試圖在Go中創建一個用於重試任何失敗查詢函數的函數(通常是因爲序列化問題)。在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 
} 

我要重新被這個樣子

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> 
} 

但功能,結果是一個編譯錯誤

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

我試圖修改它一點,我得到另一個編譯錯誤

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

任何人都可以幫助我創建一個通用函數來包裝一個函數來重試錯誤?

+2

作爲參數傳遞的函數的簽名必須函數的簽名相匹配精確的參數類型。您必須重寫您傳遞給'interface {}'的函數,並將它們轉換爲這些函數內的適當類型。 – xunatai

+0

這樣,對於N個函數,我需要N個包裝。我需要通用函數包裝來大大簡化我的代碼。 – Kuzunoha

+1

是的。或重新設計。 – Volker

回答

1

解決問題的更好方法是使用閉包。

例如,更改的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 
} 

立即調用函數以進行重試爲:

// ... 
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