2017-06-14 41 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