原文地址:http://www.niu12.com/article/14 panic知識點 package main import ( "fmt" "github.com/pkg/errors" ) func main() { outerFunc() fmt.Println(1) } func outerFunc() { innerFunc() } func innerFunc() { panic(errors.New("An intended fatal error")) } 當調用innerFunc 函數中的panic函數后,innerFunc 的執行會被停止。 緊接着,流程控制權會交回給調用方outerFunc函數。 然后, outerFunc函數的執行也將被停止。運行時恐慌就這樣沿着調用棧反方向進行傳播, 直至到達當前goroutine的調用棧的最頂層。-旦達到頂層,就意味着該goroutine調用棧 中所有函數的執行都已經被停止了,程序已經崩潰。 GO運行時系統也會調用panic() 函數 recover 運行時恐慌一旦被引發,就會向調用方傳播直至程序崩潰。 Go 提供了專用於“攔截” 運行時恐慌的內建函數 recover ,它可以使氣前的程序從恐慌狀態中恢復並重新獲 得流程控制權。 recover 函數被調川后,會返回一個 interfaoe { }類型的結果、 如果當時的程序正處於運行時恐慌的狀態,那么這個結果就會是非 nil 的。 func innerFunc() { defer func() { if p := recover(); p != nil { fmt.Printf("Recovered panic:%s\n", p) } }() panic(errors.New("An intended fatal error")) } 將defer 匿名函數放在函數體的開始處,可以有效防止該函數及其下層調用中的代碼引發運行時恐慌 口可以把運行時恐慌的攜帶值轉換為error類型值,並當作常規結果返回給調用方。 這樣既阻止了恐慌的擴散,又傳遞了引起恐慌的原因。 口檢查運行時恐慌攜帶值的類型,並根據類型做不同的后續動作,這樣可以精確地 控制程序的錯誤處理行為。