golang的defer,panic,recover簡單舉例

golang中defer,panic,recover是很常用的三個(gè)特性莹妒,三者一起使用可以充當(dāng)其他語言中try…catch…的角色旨怠,而defer本身又像其他語言的析構(gòu)函數(shù)

defer延遲執(zhí)行:

defer 是return 后才調(diào)用

4. 為什么要有 defer鉴腻?

看完上面的例子后爽哎,不知道你是否和我一樣倦青,對這個(gè)defer的使用效果感到熟悉盹舞?貌似在 Python 也見過類似的用法。

雖然 Python 中沒有 defer 癣亚,但是它有 with 上下文管理器获印。我們知道在 Python 中可以使用 defer 實(shí)現(xiàn)對資源的管理。最常用的例子就是文件的打開關(guān)閉玻孟。

你可能會(huì)有疑問鳍征,這也沒什么意義呀,我把這個(gè)放在 defer 執(zhí)行的函數(shù)放在 return 那里執(zhí)行不就好了匣掸。

固然可以氮双,但是當(dāng)一個(gè)函數(shù)里有多個(gè) return 時(shí),你得多調(diào)用好多次這個(gè)函數(shù)送爸,代碼就臃腫起來了碱璃。

若是沒有 defer,你可以寫出這樣的代碼

func f() { r := getResource() //0肛真,獲取資源 ...... if ... { r.release() //1爽航,釋放資源 return } ...... if ... { r.release() //2,釋放資源 return } ...... if ... { r.release() //3历极,釋放資源 return } ...... r.release() //4衷佃,釋放資源 return }

使用了 defer 后,代碼就顯得簡單直接锄列,不管你在何處 return邻邮,都會(huì)執(zhí)行 defer 后的函數(shù)克婶。

func f() { r := getResource() //0,獲取資源 defer r.release() //1鸭蛙,釋放資源 ...... if ... { ... return } ...... if ... { ... return } ...... if ... { ... return } ...... return }

還是類似于析構(gòu)函數(shù)筋岛,多個(gè)if分支和return的情況下,延遲最后執(zhí)行

panic, 手動(dòng)觸發(fā)宕機(jī)

1. 觸發(fā)panic

手動(dòng)觸發(fā)宕機(jī),是非常簡單的一件事揩晴,只需要調(diào)用 panic 這個(gè)內(nèi)置函數(shù)即可,就像這樣子

package main func main() { panic("crash") }

運(yùn)行后诅愚,直接報(bào)錯(cuò)宕機(jī)

$ go run main.go go run main.go panic: crash goroutine 1 [running]: main.main() E:/Go-Code/main.go:4 +0x40 exit status 2

2. 捕獲 panic

發(fā)生了異常违孝,有時(shí)候就得捕獲,就像 Python 中的except 一樣喇喉,那 Golang 中是如何做到的呢校坑?

這就不得不引出另外一個(gè)內(nèi)建函數(shù) -- recover,它可以讓程序在發(fā)生宕機(jī)后起生回生膏斤。

但是 recover 的使用邪驮,有一個(gè)條件,就是它必須在 defer 函數(shù)中才能生效沮榜,其他作用域下敞映,它是不工作的。

這是一個(gè)簡單的例子

package main

import "fmt"

func set_data(x int){

defer func(){

if err := recover(); err != nil {

fmt.Println(err)

}

}()

var arr [10]int

arr[x] = 88

}

func main(){

set_data(20)

fmt.Println("is ok")

}

如果不使用defer 匿名函數(shù) + recover()振愿,那么程序會(huì)直接中斷冕末,提示

panic: runtime error: index out of range [20] with length 10

使用了recover()的執(zhí)行結(jié)果為:

3. 無法跨協(xié)程

從上面的例子档桃,可以看到憔晒,即使 panic 會(huì)導(dǎo)致整個(gè)程序退出,但在退出前嘹屯,若有 defer 延遲函數(shù)从撼,還是得執(zhí)行完 defer 。

但是這個(gè) defer 在多個(gè)協(xié)程之間是沒有效果婆翔,在子協(xié)程里觸發(fā) panic,只能觸發(fā)自己協(xié)程內(nèi)的 defer啃奴,而不能調(diào)用 main 協(xié)程里的 defer 函數(shù)的。

來做個(gè)實(shí)驗(yàn)就知道了

import ( "fmt" "time" ) func main() { // 這個(gè) defer 并不會(huì)執(zhí)行 defer fmt.Println("in main") go func() { defer println("in goroutine") panic("") }() time.Sleep(2 * time.Second) }

輸出如下

in goroutine panic:

Golang 異常的拋出與捕獲畔咧,依賴兩個(gè)內(nèi)置函數(shù):

panic:拋出異常揖膜,使程序崩潰

recover:捕獲異常,恢復(fù)程序或做收尾工作

revocer 調(diào)用后拜隧,拋出的 panic 將會(huì)在此處終結(jié),不會(huì)再外拋洪添,但是 recover干奢,并不能任意使用盏袄,它有強(qiáng)制要求,必須得在 defer 下才能發(fā)揮用途辕羽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刁愿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滤钱,更是在濱河造成了極大的恐慌脑题,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡佑稠,警方通過查閱死者的電腦和手機(jī)舌胶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門疮丛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人履恩,你說我怎么就攤上這事呢蔫。” “怎么了绽昏?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵俏脊,是天一觀的道長。 經(jīng)常有香客問我认然,道長沸久,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任子刮,我火速辦了婚禮挺峡,結(jié)果婚禮上担钮,老公的妹妹穿的比我還像新娘。我一直安慰自己狭姨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布饼拍。 她就那樣靜靜地躺著,像睡著了一般漓柑。 火紅的嫁衣襯著肌膚如雪叨吮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天锋玲,我揣著相機(jī)與錄音嫩絮,去河邊找鬼围肥。 笑死剿干,一個(gè)胖子當(dāng)著我的面吹牛穆刻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榜轿,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谬盐,長吁一口氣:“原來是場噩夢啊……” “哼诚些!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砸烦,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤绞吁,失蹤者是張志新(化名)和其女友劉穎家破,沒想到半個(gè)月后购岗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藕畔,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡庄拇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年措近,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瞭郑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸭你。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袱巨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出场绿,到底是詐尸還是另有隱情嫉入,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布熬拒,位于F島的核電站垫竞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏件甥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望譬正。 院中可真熱鬧檬姥,春花似錦、人聲如沸健民。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崇堵。三九已至鸳劳,卻和暖如春也搓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背幔摸。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來泰國打工抚太, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昔案,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓庆亡,卻偏偏與公主長得像又谋,于是被迫代替她去往敵國和親彰亥。 傳聞我的和親對象是個(gè)殘疾皇子衰齐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354