2014-09-03 64 views
5

我试图了解如何从恐慌情况中恢复。通常,这样的事情会这样做:golang恢复返回值语法

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

我可以理解那些。但我见过的代码片段就像如下因素:

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

什么是(错误)部分在做什么?

回答

11

这是一个type assertion它检查error recovered是否属于某种类型。

该类型断言失败,导致运行时错误继续堆栈展开,就好像它没有被打断一样。

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

你可以看到在“Error handling and Go

客户端代码可以用一种类型的断言测试一个net.Error,然后从那些永久区分瞬态网络错误的例子。

例如,网络爬虫可能:

  • 睡眠,当它遇到临时错误
  • 否则放弃重试。
if nerr, ok := err.(net.Error); ok && nerr.Temporary() { 
    time.Sleep(1e9) 
    continue 
} 
if err != nil { 
    log.Fatal(err) 
} 

如果你有几个类型要恢复的错误,你可以使用一个类型开关处于 “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: 
      err = errors.New("Unknown panic") 
     } 
     // invalidate rep 
     rep = nil 
     // return the modified err and rep 
    } 
}()