前言
眾所周知在java或php等很多面向?qū)ο蟮恼Z言中, 異常處理是依靠throw、catch來進行的。在go語言中,panic和recover函數(shù)在作用層面分別對等throw和catch語句,當(dāng)然也存在不同之處。下面話不多說,來一起看看詳細(xì)的介紹吧。
從設(shè)計層面來看,panic和recover函數(shù)適用于那些真正的異常(例如整數(shù)除0),而throw catch finally機制常常被用來處理一些業(yè)務(wù)層面的自定義異常。因此在go語言中,panic和recover要慎用。
上述兩種異常機制的使用中,在處理異常時控制流程的走向也是相似的。
下面將分別舉例說明:
try catch finally機制
try{
throw new Exception();
} catch(Exception $e) {
do something ...
} finally {
}
這種機制中,我們把可能拋出異常的語句或拋出自定義異常的語句放置到try語句塊中,而在catch塊中,我們將上述語句拋出的異常捕獲,針對不同的異常進行報警或log等處理。之后,控制流程進入到finally語句塊中。若沒有finally語句,控制流程將進入到catch之后的語句中。也就是說,在這種機制中,控制流程是轉(zhuǎn)移到同一層級中異常捕獲之后的語句中。
panic recover defer機制
在go的異常機制中,panic可以將原有的控制流程中斷,進入到一個"恐慌"流程。這種恐慌流程可以顯式調(diào)用panic()函數(shù)產(chǎn)生或者由運行時錯誤產(chǎn)生(例如訪問越界的數(shù)組下標(biāo))。panic會在調(diào)用它的函數(shù)中向本層和它的所有上層逐級拋出,若一直沒有recover將其捕獲,程序退出后會產(chǎn)生crash;若在某層defer語句中被recover捕獲,控制流程將進入到recover之后的語句中。
/* example 1 */
package main
import (
"fmt"
)
func f() {
defer func() {
fmt.Println("b")
if err := recover();err != nil {
fmt.Println(err)
}
fmt.Println("d")
}()
fmt.Println("a")
panic("a bug occur")
fmt.Println("c")
}
func main() {
f()
fmt.Println("x")
}
在上述舉例中,輸出結(jié)果為:
這說明,在f函數(shù)中拋出的panic被自己defer語句中的recover捕獲,然后控制流程進入到recover之后的語句中,即打印d、打印x,之后進程正常退出。
/* example 2 */
package main
import (
"fmt"
)
func g() {
defer func() {
fmt.Println("b")
if err := recover();err != nil {
fmt.Println(err)
}
fmt.Println("d")
}()
f()
fmt.Println("e")
}
func f() {
fmt.Println("a")
panic("a bug occur")
fmt.Println("c")
}
func main() {
g()
fmt.Println("x")
}
上述案例的輸出結(jié)果是:
進程經(jīng)歷了這樣一個過程:f()
中拋出panic,由于自身沒有定義defer語句,panic被拋到g()中。g()
的defer語句中定義了recover,捕獲panic后并執(zhí)行完defer剩余的語句,之后控制流程被轉(zhuǎn)交到main()
函數(shù)中,直至進程結(jié)束。
總結(jié)
以上就是這篇文章的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
您可能感興趣的文章:- Go語言異常處理案例解析
- Golang中異常處理機制詳解
- 利用golang實現(xiàn)封裝trycatch異常處理實例代碼
- go語言異常panic和恢復(fù)recover用法實例
- 小學(xué)生也能看懂的Golang異常處理recover panic