golang panic及处理机制
一 panic机制
panic会将这个异常不断向上抛出,直到有地方处理它,如果有处理,则不会再向上抛出。倘若没有处理,那么最终会导致main挂掉.
golang虽然没有try catch机制,却有一种类似的recover机制,后续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能继续运行,继而main开辟的go test1也能继续运行
2.3 func用recover且开创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")) }
我们发现,func虽然挂掉了,但是他开创的go没挂掉,因为即使是这个函数退出了,新开的协程是相当于基于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") }
协程中如果没recover,那么error就会抛向main,main就会挂掉,从而没有执行到后面的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异常,执行终止,向调用者func1抛出进而本身退出,func1得到异常,执行终止,本身退出时recover进行处理,从而保活了main
到此这篇关于golang panic及处理机制的文章就介绍到这了,更多相关golang panic内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Go语言将string解析为time.Time时两种常见报错
本文主要介绍了Go语言将string解析为time.Time时两种常见报错,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-03-03Golang 使用os 库的 ReadFile() 读文件最佳实践
这篇文章主要介绍了Golang使用os库的ReadFile()读文件最佳实践,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下2022-09-09
最新评论