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

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

Pass function as argument in Go

问题

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

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

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

  1. func GetTopStudent(classId string) ([]Student, []error) {
  2. // 查询classId对应班级的前10名学生
  3. }
  4. func GetAverageStudentScores(classId string, from time.Time, until time.Time) ([]Pair, []error) {
  5. // 使用聚合查询所有学生的平均分,按照学生ID进行分组
  6. // Pair类似于C++中的pair<string, string>
  7. }

但是,结果出现了编译错误:

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

我尝试稍作修改,又得到了另一个编译错误:

  1. 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).

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

The functions I want to retry are looked like this

  1. func GetTopStudent(classId string) ([]Student, []error) {
  2. //queries top 10 students for class with classId
  3. }
  4. func GetAverageStudentScores(classId string, from time.Time, until time.Time) ([]Pair, []error) {
  5. //queries all average score using aggregate, grouping by studentId
  6. //Pair behaves like C++ pair&lt;string,string&gt;
  7. }

But, the results is a compile error

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

  1. 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的类型:

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

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

  1. // ...
  2. classId := "some value"
  3. // ...
  4. var st []Student
  5. var errors []error
  6. err := retryer(func() error {
  7. st, errors = GetTopStudent(classId)
  8. // 处理错误
  9. return nil
  10. }, numTries, waitTime)
  11. // 在这里使用 st

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

英文:

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

For example, change the type of retryer:

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

Now call functions to be retried as:

  1. // ...
  2. classId := &quot;some value&quot;
  3. // ...
  4. var st []Student
  5. var errors []error
  6. err := retryer(func() error {
  7. st, errors = GetTopStudent(classId)
  8. // handle errors
  9. return nil
  10. }, numTries, waitTime)
  11. // 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:

确定