golang?中?recover()的使用方法
Recover
是一個(gè)Go語(yǔ)言的內(nèi)建函數(shù),可以讓進(jìn)入宕機(jī)流程中的 goroutine
恢復(fù)過(guò)來(lái),recover 僅在延遲函數(shù) defer 中有效,在正常的執(zhí)行過(guò)程中,調(diào)用 recover 會(huì)返回 nil 并且沒(méi)有其他任何效果,如果當(dāng)前的 goroutine
陷入恐慌,調(diào)用 recover 可以捕獲到 panic 的輸入值,并且恢復(fù)正常的執(zhí)行。
通常來(lái)說(shuō),不應(yīng)該對(duì)進(jìn)入 panic 宕機(jī)的程序做任何處理,但有時(shí),需要我們可以從宕機(jī)中恢復(fù),至少我們可以在程序崩潰前,做一些操作,舉個(gè)例子,當(dāng) web 服務(wù)器遇到不可預(yù)料的嚴(yán)重問(wèn)題時(shí),在崩潰前應(yīng)該將所有的連接關(guān)閉,如果不做任何處理,會(huì)使得客戶端一直處于等待狀態(tài),如果 web 服務(wù)器還在開發(fā)階段,服務(wù)器甚至可以將異常信息反饋到客戶端,幫助調(diào)試。
在其他語(yǔ)言里,宕機(jī)往往以異常的形式存在,底層拋出異常,上層邏輯通過(guò)try/catch
機(jī)制捕獲異常,沒(méi)有被捕獲的嚴(yán)重異常會(huì)導(dǎo)致宕機(jī),捕獲的異??梢员缓雎裕尨a繼續(xù)運(yùn)行。
Go語(yǔ)言沒(méi)有異常系統(tǒng),其使用 panic 觸發(fā)宕機(jī)類似于其他語(yǔ)言的拋出異常,recover
的宕機(jī)恢復(fù)機(jī)制就對(duì)應(yīng)其他語(yǔ)言中的 try/catch 機(jī)
Recover的用法:
defer可以讀取有名返回值
理論:如果不進(jìn)行recover,便會(huì)導(dǎo)致整個(gè)程序掛掉,
Recover()用法是:將Recover()
寫在defer中,并且在可能發(fā)生panic的地方之前,先調(diào)用此defer的東西(讓系統(tǒng)方法域結(jié)束時(shí),有代碼要執(zhí)行。)當(dāng)程序遇到panic的時(shí)候(當(dāng)然,也可以正常的調(diào)用出現(xiàn)的異常情況),系統(tǒng)將跳過(guò)后面的代碼,進(jìn)入defer,如果defer函數(shù)中recover()
,則返回捕獲到的panic的值。
總結(jié):使用recover()捕捉panic異常的時(shí)候,則需要defer來(lái)讀取一個(gè)匿名函數(shù),
defer func(){ If err:=recover();err!=nil{//注意必須要判斷 打印捕捉的err內(nèi)容 } }()//用來(lái)調(diào)用此匿名函數(shù) package main import ( “fmt” “l(fā)og” ) func tast2() { fmt.Println(“sssssssss”) } func tast(x int) { defer func() { if err:=recover();err !=nil{ fmt.Println(err) } }() var a [10]int a[x]=1222 log.Println(a) } func main(){ tast(20) tast2() }
希望goroutine
在函數(shù)執(zhí)行時(shí)不會(huì)因崩潰導(dǎo)致剩余程序運(yùn)行,同時(shí)設(shè)置一個(gè)默認(rèn)返回值
package main import ( "fmt" "time" ) func calcRem(i int) (res int) { defer func() { if err := recover(); err != nil { fmt.Printf("error: %s\n", err) res = 999 //干擾輸出 } }() res = 10 / (10 % i) //當(dāng)余數(shù)取余為0時(shí),res為0 fmt.Printf("10 / (10 %% %d) = %d\n", i, res) return } func main() { resCH := make(chan int, 10) defer close(resCH) for i := 1; i <= 10; i++ { go func(i int) { res := calcRem(i) resCH <- res }(i) time.Sleep(time.Microsecond * 100) } time.Sleep(time.Second) fmt.Printf("ch len is: %d\n", len(resCH)) for i := 1; i <= 10; i++ { res := <-resCH fmt.Println(res) } }
output
error: runtime error: integer divide by zero
error: runtime error: integer divide by zero
10 / (10 % 3) = 10
10 / (10 % 4) = 5
error: runtime error: integer divide by zero
10 / (10 % 6) = 2
10 / (10 % 7) = 3
10 / (10 % 8) = 5
10 / (10 % 9) = 10
error: runtime error: integer divide by zero
ch len is: 10
999
999
10
5
999
2
3
5
10
999
到此這篇關(guān)于Guam與golang recover()的使用方法的文章就介紹到這了,更多相關(guān)golang recover()用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go?語(yǔ)言數(shù)據(jù)結(jié)構(gòu)如何實(shí)現(xiàn)抄一個(gè)list示例詳解
這篇文章主要為大家介紹了Go?語(yǔ)言數(shù)據(jù)結(jié)構(gòu)如何實(shí)現(xiàn)抄一個(gè)list示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Go語(yǔ)言strconv包實(shí)現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換
這篇文章主要介紹了Go語(yǔ)言strconv包實(shí)現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03詳解Golang如何使用Debug庫(kù)優(yōu)化代碼
這篇文章將針對(duì)Golang的debug庫(kù)進(jìn)行全面解讀,涵蓋其核心組件、高級(jí)功能和實(shí)戰(zhàn)技巧,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下2024-02-02Golang中常見的三種并發(fā)控制方式使用小結(jié)
這篇文章主要為大家詳細(xì)介紹了如何對(duì)goroutine并發(fā)行為的控制,在Go中最常見的有三種方式:sync.WaitGroup、channel和Context,下面我們就來(lái)看看他們的具體使用吧2024-01-01