我正在处理一个ETL类型的应用程序,我所做的大多数错误处理只是重试API请求,直到它们成功(它们偶尔会由于连接等原因而随机失败)。
for err != nil {
a,b,err = myfunc(c, d, e)
}
return a, b
因此,基本上只是继续做这个函数,直到错误消失(我把睡眠和其他错误检查作为必要的,以及避免速率限制)。
我想做的是将其简化为一个函数,该函数接受任意函数,在其输出中查找错误类型(如果它有一个),并递归地运行它,直到err!=nil。我的问题是,尽管go似乎允许使用任何(interface{})作为输入,它在函数定义上不是可变变量,例如(type func(a int)(int,int,error))作为类型func(... any)[]any
我想知道这是否是不可能做到的去,如果是这样的任何建议,以绕过它/获得类似的功能更习惯。
尝试使用类似的代码进行测试,但编译器不喜欢它。
func main() {
Deal(SometimesFail, 10)
}
func Deal(f func(...any) []any, inputs ...any) []any {
outputs := f(inputs)
for _, val := range outputs {
err, ok := val.(error)
if ok {
for err != nil {
outputs = Deal(f, inputs...)
}
return outputs
}
continue
}
return outputs
}
func SometimesFail(a int) (int, int, error) {
random := rand.Intn(a)
if random%2 == 0 {
return random, random, nil
} else {
return random, random, errors.New("error")
}
}
我想我能做的就是为每个函数的输出/输入模式创建一个类型,并允许泛型函数接受其中的任何一个,这样可以在实现目标的同时将代码重复保持在最低限度。
1条答案
按热度按时间qaxu7uf21#
以下内容:
func(any)
,func(any, any)
,func(...any)
都是不同的类型,不能将一种类型赋给另一种类型,没有一个函数类型可以包含所有这些类型。解决这个问题的一种方法是将函数调用(必须知道函数的确切类型)与重试逻辑解耦: