golang的recover返回值语法

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

golang recover return value syntax

问题

.(error) 部分是类型断言的语法,用于将 recover() 的返回值转换为 error 类型。在这个代码片段中,recover() 函数返回的结果被断言为 error 类型,并赋值给变量 r。然后通过检查 ok 变量的值,可以确定类型断言是否成功。如果成功,就可以在 fmt.Println() 中打印出错误信息。这样可以更具体地处理恢复操作中的错误情况。

英文:

I'm trying to understand how to recover from panic situation. Normally, something like this will do:

 if r := recover(); r != nil {
    fmt.Println("Recovered in f", r)
 }

I can understand those much. But I've seen code snippet like the following:

 if r, ok := recover().(error); ok {
    fmt.Println("Recovered in f", r)
 }

What's the .(error) part doing?

答案1

得分: 29

这是一种类型断言,用于检查恢复的错误是否属于某种特定类型。

如果类型断言失败,会导致运行时错误,继续堆栈展开,就好像没有中断一样。

当你为错误定义一个本地的MyError类型,并且只想从该类型中恢复时,这非常有用。

你可以在“错误处理和Go”中看到一个例子。

> 客户端代码可以通过类型断言来测试是否为net.Error,然后区分临时网络错误和永久性错误。

> 例如,一个网络爬虫可能会:

> - 在遇到临时错误时休眠并重试

  • 否则放弃。

    if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
    time.Sleep(1e9)
    continue
    }
    if err != nil {
    log.Fatal(err)
    }


如果你有多种类型的错误需要恢复,可以使用类型开关,如“Golang:从defer返回”中所示。

defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered in f", r)
        // 找出确切的错误并设置err
        switch x := r.(type) {
        case string:
            err = errors.New(x)
        case error:
            err = x
        default:
            // 默认错误(根据规范,错误字符串应为小写且不带标点符号)
            err = errors.New("unknown panic")
        }
        // 使rep无效
        rep = nil
        // 返回修改后的err和rep
    }
}()
英文:

It is a type assertion which check if the error recovered is of a certain type.

It that type assertion fails, that causes a run-time error that continues the stack unwinding as though nothing had interrupted it.

This is useful when you define a local MyError type for error, and you want to recover only from that type.

You can see an example in "Error handling and Go"

> Client code can test for a net.Error with a type assertion and then distinguish transient network errors from permanent ones.

> For instance, a web crawler might:

> - sleep and retry when it encounters a temporary error

  • and give up otherwise.

    if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
    time.Sleep(1e9)
    continue
    }
    if err != nil {
    log.Fatal(err)
    }


If you have several types of error you want to recover, you can use a type switch is in "Golang: returning from defer"

defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered in f", r)
        // find out exactly what the error was and set err
        switch x := r.(type) {
        case string:
            err = errors.New(x)
        case error:
            err = x
        default:
            // Fallback err (per specs, error strings should be lowercase w/o punctuation
            err = errors.New("unknown panic")
        }
        // invalidate rep
        rep = nil
        // return the modified err and rep
    }
}()

huangapple
  • 本文由 发表于 2014年9月3日 15:40:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/25638842.html
匿名

发表评论

匿名网友

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

确定