2014-09-03 60 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 
    } 
}()