在Go语言中,可以将函数作为参数传递。

huangapple go评论78阅读模式
英文:

Pass function as argument in Go

问题

我已经尝试在Go语言中创建一个函数,用于重试任何失败的查询函数(通常是由于序列化问题)。

func retryer(functionA func(interface{}) (interface{}, []error), maxRetry int, waitBetween time.Duration) interface{} {
    // 当functionA没有错误时,retryer返回functionA的返回值
    // 当达到最大重试次数时,返回nil
}

我想要重试的函数看起来像这样:

func GetTopStudent(classId string) ([]Student, []error) {
    // 查询classId对应班级的前10名学生
}

func GetAverageStudentScores(classId string, from time.Time, until time.Time) ([]Pair, []error) {
    // 使用聚合查询所有学生的平均分,按照学生ID进行分组
    // Pair类似于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

有人可以帮我创建一个通用的函数,用于包装一个函数并在出现错误时进行重试吗?

英文:

I've tried to create a function in Go that used to retry any fail query functions (usually because serialization issue).

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
}

The functions I want to retry are looked like this

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&lt;string,string&gt;
}

But, the results is a compile error

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

I've tried to modify it a little and I got another compile error

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

Can anyone help me creating a general function to wrap a function to retry on error?

答案1

得分: 3

更好的解决方法是使用闭包。

例如,更改retryer的类型:

func retryer(f func() error, maxRetry int, waitBetween time.Duration) error {
    // 重试和等待逻辑
    err := f()
    // 错误处理、重试和等待逻辑
    return err
}

现在调用需要重试的函数:

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

var st []Student
var errors []error
err := retryer(func() error {
    st, errors = GetTopStudent(classId)
    // 处理错误
    return nil
}, numTries, waitTime)
// 在这里使用 st

请注意,以上代码是使用Go语言编写的示例代码,用于演示如何使用闭包解决问题。

英文:

A better way to solve your problem would be to use closures.

For example, change the type of 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
}

Now call functions to be retried as:

// ...
classId := &quot;some value&quot;
// ...

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

huangapple
  • 本文由 发表于 2017年6月14日 12:10:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/44535260.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定