golang panic及處理機(jī)制
一 panic機(jī)制
panic會(huì)將這個(gè)異常不斷向上拋出,直到有地方處理它,如果有處理,則不會(huì)再向上拋出。倘若沒(méi)有處理,那么最終會(huì)導(dǎo)致main掛掉.
golang雖然沒(méi)有try catch機(jī)制,卻有一種類(lèi)似的recover機(jī)制,后續(xù)demo我們可以觀測(cè)到它的用法和作用
二 實(shí)例
2.1 main用recover
func main() { defer func() { if err := recover(); err != nil { log.Println("err:", err) } }() go test1() time.Sleep(time.Second * 3) panic(errors.New("stop test1")) log.Println("123") select {} } func test1() { for { tm := time.NewTicker(time.Second) select { case <-tm.C: log.Println("test1") } } }
2.2 func用recover
func main() { defer func() { if err := recover(); err != nil { log.Println("err:", err) } }() go test1() time.Sleep(time.Second * 3) makeerr() log.Println("123") select {} } func test1() { for { tm := time.NewTicker(time.Second) select { case <-tm.C: log.Println("test1") } } } func makeerr() { defer func() { if err := recover(); err != nil { log.Println("makeerr:", err) } }() panic(errors.New("stop")) }
此時(shí)我們?cè)趂unc中用recover,那么掛掉的只是func,他不會(huì)拋到main中,所以main能繼續(xù)運(yùn)行,繼而main開(kāi)辟的go test1也能繼續(xù)運(yùn)行
2.3 func用recover且開(kāi)創(chuàng)goroutine
func main() { defer func() { if err := recover(); err != nil { log.Println("err:", err) } }() time.Sleep(time.Second * 3) makeerr() log.Println("123") select {} } func test1() { for { tm := time.NewTicker(time.Second) select { case <-tm.C: log.Println("test1") } } } func makeerr() { defer func() { if err := recover(); err != nil { log.Println("makeerr err:", err) } }() go test1() panic(errors.New("stop test")) }
我們發(fā)現(xiàn),func雖然掛掉了,但是他開(kāi)創(chuàng)的go沒(méi)掛掉,因?yàn)榧词故沁@個(gè)函數(shù)退出了,新開(kāi)的協(xié)程是相當(dāng)于基于main下的一個(gè)子程,只要main不退出,他依然會(huì)“存活”
2.4 goroutine中panic
func main() { defer func() { if err := recover(); err != nil { log.Println("err:", err) } }() go test1() time.Sleep(time.Second * 3) log.Println("123") select {} } func test1() { log.Println("test1 start") panic(errors.New("stop test1")) log.Println("test1 end") }
協(xié)程中如果沒(méi)recover,那么error就會(huì)拋向main,main就會(huì)掛掉,從而沒(méi)有執(zhí)行到后面的log打印。
---> 這種情況,main中做defer recover是沒(méi)用的
2.5 func1內(nèi)嵌func2中panic且func2做處理
func main() { test1() time.Sleep(time.Second * 3) log.Println("123") } func test1() { log.Println("test1 start") test2() log.Println("test1 end") } func test2() { defer func() { if err := recover(); err != nil { log.Println("test2 err:", err) } }() log.Println("test2 start") panic(errors.New("stop test2")) log.Println("test2 end") }
2.6 func1內(nèi)嵌func中panic且func1做處理
func main() { test1() time.Sleep(time.Second * 3) log.Println("123") } func test1() { defer func() { if err := recover(); err != nil { log.Println("test? err:", err) } }() log.Println("test1 start") test2() log.Println("test1 end") } func test2() { log.Println("test2 start") panic(errors.New("stop test2")) log.Println("test2 end") }
func2異常,執(zhí)行終止,向調(diào)用者func1拋出進(jìn)而本身退出,func1得到異常,執(zhí)行終止,本身退出時(shí)recover進(jìn)行處理,從而?;盍薽ain
到此這篇關(guān)于golang panic及處理機(jī)制的文章就介紹到這了,更多相關(guān)golang panic內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言將string解析為time.Time時(shí)兩種常見(jiàn)報(bào)錯(cuò)
本文主要介紹了Go語(yǔ)言將string解析為time.Time時(shí)兩種常見(jiàn)報(bào)錯(cuò),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Golang多線程爬蟲(chóng)高效抓取大量數(shù)據(jù)的利器
Golang多線程爬蟲(chóng)是一種高效抓取大量數(shù)據(jù)的利器。Golang語(yǔ)言天生支持并發(fā)和多線程,可以輕松實(shí)現(xiàn)多線程爬蟲(chóng)的開(kāi)發(fā)。通過(guò)使用Golang的協(xié)程和通道,可以實(shí)現(xiàn)爬蟲(chóng)的高效并發(fā)抓取、數(shù)據(jù)處理和存儲(chǔ)2023-05-05go實(shí)現(xiàn)服務(wù)優(yōu)雅關(guān)閉的示例
本文主要介紹了go實(shí)現(xiàn)服務(wù)優(yōu)雅關(guān)閉的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Golang中unicode碼和中文的互相轉(zhuǎn)換函數(shù)使用
這篇文章主要為大家介紹了Golang中unicode碼和中文的互相轉(zhuǎn)換函數(shù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09

Go?常見(jiàn)設(shè)計(jì)模式之單例模式詳解

Golang?使用os?庫(kù)的?ReadFile()?讀文件最佳實(shí)踐