go 异常捕获处理 panic defer recover
簡言
在其他語言里,宕機往往以異常的形式存在,底層拋出異常,上層邏輯通過 try/catch 機制捕獲異常,沒有被捕獲的嚴重異常會導(dǎo)致宕機
go語言追求簡潔,優(yōu)雅,Go語言不支持傳統(tǒng)的 try…catch…finally 這種異常
Go語言的設(shè)計者們認為,將異常與控制結(jié)構(gòu)混在一起會很容易使得代碼變得混亂
Go語言,可以使用多值返回來返回錯誤。不要用異常代替錯誤,更不要用來控制流程。在極個別的情況下,才使用Go中引入的Exception處理:defer, panic, recover
Go中,對異常處理的原則是:多用error包,少用panic
panic() 函數(shù)
函數(shù)中遇到panic語句,會立即終止當(dāng)前函數(shù)的執(zhí)行,在panic所在函數(shù)內(nèi)如果存在要執(zhí)行的defer函數(shù)列表,按照defer的逆序執(zhí)行
recover() 函數(shù)
recover函數(shù)的返回值報告協(xié)程是否正在遭遇panic
有異常時,recover()只能調(diào)用一次,后面再次調(diào)用則捕獲不到任何異常
通常辦法:go中可以拋出一個panic的異常,然后在defer中通過recover捕獲這個異常,然后正常處理,從而恢復(fù)正常代碼的執(zhí)行
實驗如下圖:
實驗代碼如下(已添加詳細注釋,不再一一詳述):
package main import ("fmt""runtime/debug" )// 異常處理函數(shù)1 func panicDeal1() {fmt.Println("panicDeal1,begin")if err := recover(); err != nil {fmt.Println("err1:", err) // 打印出異常(由于panicDeal2()中的recover函數(shù)已經(jīng)捕獲了異常,所以這里捕獲不到異常,不會得到執(zhí)行)fmt.Println(string(debug.Stack())) // 打印出堆棧信息}fmt.Println("panicDeal1,end") }// 異常處理函數(shù)2 func panicDeal2() {fmt.Println("panicDeal2,begin")if err := recover(); err != nil {fmt.Println("err2", err) // 打印出異常fmt.Println(string(debug.Stack())) // 打印出堆棧}fmt.Println("panicDeal2,end") }func test() {fmt.Println("1111")// 必須先聲明defer,否則不能捕獲panic異常defer panicDeal1()// 觸發(fā)panic時,逆序執(zhí)行,也就是先執(zhí)行 panicDeal2(),再執(zhí)行 panicDeal1()defer panicDeal2()fmt.Println("2222")// 空指針賦值,產(chǎn)生崩潰var p *int*p = 1// 這里的代碼得不到執(zhí)行fmt.Println("3333") }func main() {test() }?
總結(jié)
以上是生活随笔為你收集整理的go 异常捕获处理 panic defer recover的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: golang 数组 切片 下标范围
- 下一篇: redis 慢查询日志