这篇文章主要讲解了“golang recover函数使用的坑怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“golang recover函数使用的坑怎么解决”吧!
package main import "fmt" func main(){ defer func(){ if err := recover();err != nil{ fmt.Printf("err = %v",err) } }() panic("a panic") } 打印结果: err = a panic Process finished with exit code 0
能正常catch panic
之前线上环境出现过接口出现panic导致服务不可用的情况,于是同事就直接在main函数加了个recover认为万事无忧了。实际上recover并不能捕捉到协程中的panic。
package main import "fmt" func main(){ defer func(){ if err := recover();err != nil{ fmt.Printf("err = %v",err) } }() go func(){ panic("a panic") }() select{} } 打印结果: panic: a panic goroutine 6 [running]: main.main.func2() I:/goProject/catchPanic.go:13 +0x40 created by main.main I:/goProject/catchPanic.go:12 +0x5e
实际上还是会panic导致服务不可用。
正确写法
package main import "fmt" func main(){ go func(){ defer func(){ if err := recover();err != nil{ fmt.Printf("err = %v",err) } }() panic("a panic") }() select {} } 返回值: fatal error: all goroutines are asleep - deadlock! goroutine 1 [select (no cases)]: main.main() I:/goProject/catchPanic.go:15 +0x41 err = a panic Process finished with exit code 2
可以看到panic被正常捕捉,同时因为select语句陷入阻塞,报了一个死锁的错。
在我想要把recover封装成成一个函数的时候,发现recover并没有生效,因为recover只有在被defer语句直接调用的时候才会生效。当recover在其他函数内部的时候无法正确捕捉到panic。
package main import "fmt" func main(){ defer cover() panic("a panic") } func cover(){ defer func(){ if err := recover();err!= nil{ fmt.Println(err) } }() } 返回值: panic: a panic goroutine 1 [running]: main.main() I:/goProject/catchPanic.go:7 +0x62
panic要被捕捉,还需要满足一种条件,就是panic不是nil panic,否则在进行捕获判断的时候无法知道是panic没有发生还是panic本身就是nil。
例如以下代码
package main import "fmt" func main() { defer func(){ if err := recover();err != nil{ fmt.Println(err) } fmt.Println("after recover") }() panic(nil) select{} } 返回值: after recover
recover并没有正确处理异常,因为异常的值为nil。
感谢各位的阅读,以上就是“golang recover函数使用的坑怎么解决”的内容了,经过本文的学习后,相信大家对golang recover函数使用的坑怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。