golang-try
golang官方没有try关键字做代码尝试执行,但github中有人为其做了个try功能的语法糖。
try用法举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| 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 })
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。
golang-try包源码解析
源码list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package try
import "errors"
var MaxRetries = 10
var errMaxRetriesReached = errors.New("exceeded retry limit")
type Func func(attempt int) (retry bool, err error)
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 }
func IsMaxRetries(err error) bool { return err == errMaxRetriesReached }
|
源码解析
- 从包源码结构中看,两个执行函数,
Do和IsMaxRetries。
Do
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时,则继续重试执行。