panic
- Go 采用明確的 error 值和類似異常的 panic 機(jī)制的方式作為獨(dú)有的錯(cuò)誤處理機(jī)制。
-
Go中可以拋出一個(gè)panic的異常樊展,然后在defer中通過recover捕獲這個(gè)異常,然后正常處理
四苇。 -
由于 panic 會引起程序的崩潰橄务,因此 panic 一般用于嚴(yán)重錯(cuò)誤难礼,如程序內(nèi)部的邏輯不一致
臀栈。 當(dāng) panic() 觸發(fā)的宕機(jī)發(fā)生時(shí)蔫慧,panic() 后面的代碼將不會被運(yùn)行,但是在 panic() 函數(shù)前面已經(jīng)運(yùn)行過的 defer 語句依然會在宕機(jī)發(fā)生時(shí)發(fā)生作用
recover
在其他語言里权薯,宕機(jī)往往以異常的形式存在姑躲,底層拋出異常,上層邏輯通過 try/catch 機(jī)制捕獲異常盟蚣,沒有被捕獲的嚴(yán)重異常會導(dǎo)致宕機(jī)黍析,捕獲的異常可以被忽略屎开,讓代碼繼續(xù)運(yùn)行阐枣。
Go語言沒有異常系統(tǒng),其使用 panic 觸發(fā)宕機(jī)類似于其他語言的拋出異常奄抽,recover 的宕機(jī)恢復(fù)機(jī)制就對應(yīng)其他語言中的 try/catch 機(jī)制侮繁。
panic 和 recover 的關(guān)系
有 panic 沒 recover,程序宕機(jī)
如孝。
有 panic 也有 recover,程序不會宕機(jī)
娩贷,執(zhí)行完對應(yīng)的 defer 后第晰,從宕機(jī)點(diǎn)退出當(dāng)前函數(shù)后繼續(xù)執(zhí)行。recover()必須搭配defer使用,defer要在可能引發(fā)panic之前定義
func f1() {
fmt.Println("run f1")
}
func f2() {
fmt.Println("打開數(shù)據(jù)庫連接...")
defer func(){
err := recover()
fmt.Println(err)
fmt.Println("釋放數(shù)據(jù)庫連接...")
}()
panic("出現(xiàn)嚴(yán)重錯(cuò)誤彬祖!")
fmt.Println("run after")
}
func f3() {
fmt.Println("run f3")
}
func main() {
f1()
f2()
f3()
}
執(zhí)行結(jié)果:
run f1
打開數(shù)據(jù)庫連接...
出現(xiàn)嚴(yán)重錯(cuò)誤茁瘦!
釋放數(shù)據(jù)庫連接...
run f3
defer
- defer用來聲明一個(gè)延遲函數(shù),把這個(gè)函數(shù)放入到一個(gè)
棧
上储笑, 當(dāng)外部的包含方法return之前甜熔,返回參數(shù)到調(diào)用方法之前調(diào)用,也可以說是運(yùn)行到最外層方法體的"}"時(shí)調(diào)用突倍。我們經(jīng)常用他來做一些資源的釋放腔稀,比如關(guān)閉io操作 - 當(dāng)有多個(gè)defer時(shí)執(zhí)行順序逆向的盆昙,
后進(jìn)先出