这篇文章主要介绍了golang中panic及处理机制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
panic会将这个异常不断向上抛出,直到有地方处理它,如果有处理,则不会再向上抛出。倘若没有处理,那么最终会导致main挂掉.
golang虽然没有try catch机制,却有一种类似的recover机制,后续demo我们可以观测到它的用法和作用
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") } } }
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也能继续运行
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不退出,他依然会“存活”
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是没用的
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") }
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及处理机制的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。