try - KerwinKoo/KerwinKoo.github.io GitHub Wiki
golang官方没有try关键字做代码尝试执行,但github中有人为其做了个try功能的语法糖。
package main
import (
"errors"
"fmt"
"github.com/matryer/try"
"math/rand"
"time"
)
func main() {
var value string
err := try.Do(func(attempt int) (bool, error) {
var err error
value, err = randomFunc()
if err != nil {
fmt.Println("run error:", err)
} else {
fmt.Println("run ok:", value)
}
return attempt < 5, err //设置尝试次数,即尝试5次
})
if err != nil {
fmt.Println("ERROR:", err)
}
}
func randomFunc() (string, error) {
rand_seed := rand.New(rand.NewSource(time.Now().UnixNano()))
if rand_seed.Intn(100) < 50 {
return "test ok", nil
} else {
return "", errors.New("test error")
}
}代码解释:
- try退出条件:1、达到尝试次数:5次(默认+最高尝试次数是10次)\;或者2、执行函数的返回值中error变量值为nil。
package try
import "errors"
// MaxRetries is the maximum number of retries before bailing.
var MaxRetries = 10
var errMaxRetriesReached = errors.New("exceeded retry limit")
// Func represents functions that can be retried.
type Func func(attempt int) (retry bool, err error)
// Do keeps trying the function until the second argument
// returns false, or no error is returned.
func Do(fn Func) error {
var err error
var cont bool
attempt := 1
for {
cont, err = fn(attempt)
if !cont || err == nil {
break
}
attempt++
if attempt > MaxRetries {
return errMaxRetriesReached
}
}
return err
}
// IsMaxRetries checks whether the error is due to hitting the
// maximum number of retries or not.
func IsMaxRetries(err error) bool {
return err == errMaxRetriesReached
}- 从包源码结构中看,两个执行函数,
Do和IsMaxRetries。
Do的参数是类型为func(attempt int) (retry bool, err error)的函数指针,因此参数的定义格式必须满足Func自定义类的格式要求。该函数参数有两个返回值,retry和err,这两个返回值是try是否退出尝试的关键标准,if !cont || err == nil判定语句中标识,retry(即cont)为false或err没有报错时,函数退出。因此在使用try.Do时,必须指定这两个变量。
次数控制由Do中attempt变量决定。attempt每执行一次自动+1,并传入Func参数中,Func参数根据指定的循环try次数,决定retry返回值是否为true,当true时,则继续重试执行。