




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Golang中panic的異常處理目錄前言如何恢復(fù)panic造成的程序崩潰何時(shí)使用panic
前言
Golang中當(dāng)程序發(fā)生致命異常時(shí)(比如數(shù)組下標(biāo)越界,注意這里的異常并不是error),Golang程序會(huì)panic(運(yùn)行時(shí)恐慌)。當(dāng)程序發(fā)生panic時(shí),程序會(huì)執(zhí)行當(dāng)前棧中的defer函數(shù)列表。然后打印引發(fā)panic的具體信息,最后進(jìn)程退出,本篇文章我們一起探討Golang中的panic以及如何利用defer和recover來(lái)恢復(fù)這種致命的異常
分析造成panic堆棧信息
funcmain(){
f1()
fmt.Println("mainfuncend")
funcf1(){
fmt.Println("funcf1start")
arr:=[]int{}
fmt.Println(arr[10])
fmt.Println("funcf1end")
}
上述代碼中,我在main函數(shù)(主協(xié)程)中調(diào)用了f1函數(shù),在調(diào)用完該函數(shù)后,我打印了「mainfuncend」,程序如果正常執(zhí)行的話會(huì)輸出
funcf1start
funcf1end
mainfuncend
很明顯我們可以看出f1函數(shù)中,切片arr是沒(méi)有索引為10的元素的,這個(gè)時(shí)候程序運(yùn)行時(shí)會(huì)造成panic,下面是程序panic時(shí),console打印的堆棧信息
funcf1start
panic:runtimeerror:indexoutofrange[10]withlength0
goroutine1[running]:
main.f1()
/Users/carlos/go/src/test/demo01.go:15+0x78
main.main()
/Users/carlos/go/src/test/demo01.go:8+0x20
Processfinishedwiththeexitcode2
我們從堆棧中可以發(fā)現(xiàn):
程序會(huì)在造成panic所處的位置終止
我們可以看到錯(cuò)誤信息中只輸出了funcf1start
產(chǎn)生panic的原因
panic:runtimeerror:indexoutofrange[10]withlength0
是哪里造成的panic
goroutine1[running]//運(yùn)行該程序的協(xié)程
main.f1()
/Users/carlos/go/src/test/demo01.go:15+0x78//f1函數(shù),當(dāng)前demo01文件的低15行
main.main()
/Users/carlos/go/src/test/demo01.go:8+0x20//main函數(shù),當(dāng)前文件的弟8行
從上面的panic詳情我們可以看出,錯(cuò)誤鏈?zhǔn)峭ㄟ^(guò)棧的形式展現(xiàn)出來(lái)的(mian函數(shù)先調(diào)用,然后在mian中調(diào)用f1),所以大家以后在程序發(fā)生panic時(shí)查看堆棧信息時(shí)可以先看最上層的錯(cuò)誤,因?yàn)檫@里是造成panic的根本原因
如何恢復(fù)panic造成的程序崩潰
Golang中提供了recover函數(shù)用來(lái)恢復(fù)因panic造成的程序崩潰。recover函數(shù)有一個(gè)返回值來(lái)告訴我們panic產(chǎn)生的具體原因。下面我們通過(guò)代碼來(lái)進(jìn)行演示
funcmain(){
f1()
r:=recover()
fmt.Printf("%s\n",r)
fmt.Println("mainfuncend")
funcf1(){
fmt.Println("funcf1start")
arr:=[]int{}
fmt.Println(arr[10])
fmt.Println("funcf1end")
}
上述代碼中我只是在調(diào)用f1函數(shù)的下一行調(diào)用了recover函數(shù),這樣一來(lái)我們的理想狀態(tài)了能夠恢復(fù)程序,讓程序執(zhí)行完main函數(shù)中剩下的代碼(打印panic信息,最后打印mainfuncend),當(dāng)我們運(yùn)行該程序的時(shí)候發(fā)現(xiàn)recover并沒(méi)有起到作用,這是因?yàn)楫?dāng)f1造成panic時(shí),f1下方的recover函數(shù)根本沒(méi)有機(jī)會(huì)執(zhí)行。
下面我將上述代碼進(jìn)行一個(gè)簡(jiǎn)單的改造:
funcmain(){
deferfunc(){
fmt.Println("deferfuncstart")
ifr:=recover();r!=nil{
fmt.Printf("%s\n",r)
}
fmt.Println("deferfuncend")
}()
f1()
fmt.Println("mainfuncend")
funcf1(){
fmt.Println("funcf1start")
arr:=[]int{}
fmt.Println(arr[10])
fmt.Println("funcf1end")
}
輸出
funcf1start
deferfuncstart
runtimeerror:indexoutofrange[10]withlength0
deferfuncend
上述代碼中,我只是在main函數(shù)最開(kāi)頭添加了一個(gè)defer函數(shù),并在該函數(shù)中調(diào)用了recover函數(shù)。注意,我們?cè)谖恼碌淖铋_(kāi)頭已經(jīng)說(shuō)明了,當(dāng)程序發(fā)生panic時(shí),程序會(huì)依次執(zhí)行棧中的defer函數(shù)(關(guān)于defer函數(shù)請(qǐng)閱讀官網(wǎng)描述)。所以當(dāng)前程序發(fā)生panic時(shí)在進(jìn)程退出之前會(huì)走到defer函數(shù)中執(zhí)行recover函數(shù),recover函數(shù)會(huì)恢復(fù)當(dāng)前進(jìn)程并打印錯(cuò)誤信息。
這里我需要特別提醒你一點(diǎn),最好將defer語(yǔ)句寫(xiě)在函數(shù)的最前面。如果上述例子我將f1的調(diào)用寫(xiě)在defer函數(shù)之前,你會(huì)發(fā)現(xiàn)recover函數(shù)還是沒(méi)有執(zhí)行
funcmain(){
f1()
deferfunc(){
fmt.Println("deferfuncstart")
ifr:=recover();r!=nil{
fmt.Printf("%s\n",r)
}
fmt.Println("deferfuncend")
}()
fmt.Println("mainfuncend")
}
這是因?yàn)閒1造成panic時(shí),defer函數(shù)根本就沒(méi)有壓入函數(shù)調(diào)用棧中。
何時(shí)使用panic
當(dāng)你的項(xiàng)目中特別依賴(lài)一些組件時(shí),比如一些web項(xiàng)目中經(jīng)常會(huì)在進(jìn)程啟動(dòng)之前初始化一些mysql,mq句柄。這些實(shí)例對(duì)業(yè)務(wù)來(lái)說(shuō)是非常重要的,所以當(dāng)這些實(shí)例初始化失敗時(shí)我們可以直接讓當(dāng)前程序panic(手動(dòng)panic),然后及時(shí)發(fā)現(xiàn)問(wèn)題并解決。這樣總比你
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 理論結(jié)合實(shí)踐的語(yǔ)文試題及答案解析
- 醫(yī)療行業(yè)庫(kù)存管理與成本控制策略
- 2025年文化概論考試中的知識(shí)點(diǎn)關(guān)聯(lián)與試題及答案
- 護(hù)理學(xué)科授權(quán)體系試題及答案2025
- 行政管理專(zhuān)科自考多元試題及答案探討
- 理論與實(shí)踐衛(wèi)生資格考試試題及答案
- 2025年行政管理經(jīng)濟(jì)法概論試題剖析及答案
- 執(zhí)業(yè)藥師健康干預(yù)策略試題及答案
- 自考2025年行政管理團(tuán)隊(duì)合作試題及答案
- 練習(xí)題助力2025年執(zhí)業(yè)藥師通過(guò)試題及答案
- 醫(yī)院死亡證明培訓(xùn)課件
- 2024山東能源集團(tuán)中級(jí)人才庫(kù)選拔高頻考題難、易錯(cuò)點(diǎn)模擬試題(共500題)附帶答案詳解
- 旅游服務(wù)行業(yè)的自我品牌推廣與營(yíng)銷(xiāo)
- 面部抗衰培訓(xùn)課件
- 醫(yī)院輸血反應(yīng)應(yīng)急預(yù)案演練腳本
- 基于PLC的網(wǎng)球自動(dòng)發(fā)射機(jī)課程設(shè)計(jì)說(shuō)明書(shū)
- 介紹哈薩克族的課件
- 高速公路事故應(yīng)急處理
- 家庭分家協(xié)議書(shū)15篇
- 固體廢物的可持續(xù)發(fā)展和循環(huán)經(jīng)濟(jì)
- 量子芯片集成
評(píng)論
0/150
提交評(píng)論