golang panic及處理機制
一 panic機制
panic會將這個異常不斷向上拋出,直到有地方處理它,如果有處理,則不會再向上拋出。倘若沒有處理,那么最終會導致main掛掉.
golang雖然沒有try catch機制,卻有一種類似的recover機制,后續(xù)demo我們可以觀測到它的用法和作用
二 實例
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")) }
此時我們在func中用recover,那么掛掉的只是func,他不會拋到main中,所以main能繼續(xù)運行,繼而main開辟的go test1也能繼續(xù)運行
2.3 func用recover且開創(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ā)現,func雖然掛掉了,但是他開創(chuàng)的go沒掛掉,因為即使是這個函數退出了,新開的協(xié)程是相當于基于main下的一個子程,只要main不退出,他依然會“存活”
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é)程中如果沒recover,那么error就會拋向main,main就會掛掉,從而沒有執(zhí)行到后面的log打印。
---> 這種情況,main中做defer recover是沒用的
2.5 func1內嵌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內嵌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í)行終止,向調用者func1拋出進而本身退出,func1得到異常,執(zhí)行終止,本身退出時recover進行處理,從而?;盍薽ain
到此這篇關于golang panic及處理機制的文章就介紹到這了,更多相關golang panic內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用IDEA配置GO語言的開發(fā)環(huán)境備忘錄
最近在配置idea開發(fā)go語言時碰到很多問題,想著很多人都可能會遇到,所以下面這篇文章主要給大家介紹了關于使用IDEA配置GO語言的開發(fā)環(huán)境,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2024-05-05go 迭代string數組操作 go for string[]
這篇文章主要介紹了go 迭代string數組操作 go for string[],具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12