说说Golang异常捕获

haicoder_ibai · · 1149 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

> 原文地址:**[嗨客网](https://haicoder.net/note/golang/golang-panic-recover.html)** # Golang panic recover详解 ## Golang panic recover详解教程 **[Go 语言](https://haicoder.net/golang/golang-tutorial.html)** 中的 **[panic](https://haicoder.net/golang/golang-panic.html)** 的作用就是抛出一条错误信息,从它的参数类型可以看到它可以抛出任意类型的错误信息。在函数执行过程中的某处调用了 panic,则立即抛出一个错误信息,同时函数的正常执行流程终止,但是该函数中 panic 之前定义的 defer 语句将被依次执行。之后该 **[goroutine](https://haicoder.net/golang/golang-goroutine.html)** 立即停止执行。 recover() 用于将 panic 的信息捕捉。recover 必须定义在 panic 之前的 defer 语句中。在这种情况下,当 panic 被触发时,该 goroutine 不会简单的终止,而是会执行在它之前定义的 defer 语句。 ## Golang panic recover详解 ### 语法 ```go defer func() { if err := recover(); err != nil { fmt.Println("Panic recover, Err =", err, "Stack =", string(debug.Stack())) } }() ``` ### 说明 当发生异常时,我们使用了 recover 恢复,并打印了错误信息和堆栈信息。 ## panic无recover ### 说明 如果在一个函数中,遇到了 panic,并且没有 recover,那么程序直接终止 ### 案例 ```go package main import ( "fmt" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") var hMap map[string]string hMap["name"] = "haicoder" } ``` 此时,我们运行程序,控制台输出如下: ![](https://haicoder.net/uploads/pic/notes/golang/17_Go%E8%AF%AD%E8%A8%80panic%20recover.png) 我们给一个空 **[map](https://haicoder.net/golang/golang-map.html)** 赋值,结果程序发生了 panic,因为,我们没有 recover,因此,程序异常终止了。 ## panic有recover ### 说明 如果在一个函数中,遇到了 panic,并且有 recover,那么程序不会终止 ### 案例 ```go package main import ( "fmt" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") defer func() { if err := recover(); err != nil { fmt.Println("Panic recover, Err =", err) } }() var hMap map[string]string hMap["name"] = "haicoder" fmt.Println("Over") } ``` 此时,我们运行程序,控制台输出如下: ![](https://haicoder.net/uploads/pic/notes/golang/18_Go%E8%AF%AD%E8%A8%80panic%20recover.png) 这次,在函数里面,我们使用了 recover 捕获错误,我们看到,此时程序不再报错了,并且,异常下面的代码不会再继续执行了。 ## 子函数panic有recover ### 说明 子函数 panic ,并且有 recover,不影响主函数的执行 ### 案例 ```go package main import ( "fmt" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") fmt.Println(fun1(10, 5)) fmt.Println(fun1(10, 0)) fmt.Println(fun1(10, 2)) fmt.Println("Over") } func fun1(a, b int)int{ defer func() { if err := recover(); err != nil { fmt.Println("Panic recover, Err =", err) } }() return a / b } ``` 此时,我们运行程序,控制台输出如下: ![](https://haicoder.net/uploads/pic/notes/golang/19_Go%E8%AF%AD%E8%A8%80panic%20recover.png) 我们在子函数里面,发生了 panic,并且使用了 recover,此时在调用函数里面,调用子函数,并不影响主函数的执行。 ## 子函数panic主函数recover ### 说明 子函数 panic,主函数 recover,程序不会终止执行 ### 案例 ```go package main import ( "fmt" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") defer func() { if err := recover(); err != nil { fmt.Println("Panic recover, Err =", err) } }() fmt.Println(fun1(10, 5)) fmt.Println(fun1(10, 0)) fmt.Println(fun1(10, 2)) fmt.Println("Over") } func fun1(a, b int)int{ return a / b } ``` 此时,我们运行程序,控制台输出如下: ![](https://haicoder.net/uploads/pic/notes/golang/20_Go%E8%AF%AD%E8%A8%80panic%20recover.png) 我们在子函数里面,发生了 panic,并且在主函数使用了 recover,此时程序不会终止执行。 ## 子协程panic主函数recover ### 说明 子协程 panic,主函数 recover,程序会终止执行 ### 案例 ```go package main import ( "fmt" "time" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") defer func() { if err := recover(); err != nil { fmt.Println("Panic recover, Err =", err) } }() go fun1(10, 5) go fun1(10, 0) go fun1(10, 2) fmt.Println("Over") time.Sleep(10*time.Second) } func fun1(a, b int)int{ return a / b } ``` 此时,我们运行程序,控制台输出如下: ![](https://haicoder.net/uploads/pic/notes/golang/21_Go%E8%AF%AD%E8%A8%80panic%20recover.png) 我们在子协程里面,发生了 panic,并且在主函数使用了 recover,此时程序会终止执行。 ## 子协程panic子协程recover ### 说明 子协程 panic,子协程 recover,不影响主函数执行 ### 案例 ```go package main import ( "fmt" "time" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") go fun1(10, 5) go fun1(10, 0) go fun1(10, 2) fmt.Println("Over") time.Sleep(10*time.Second) } func fun1(a, b int)int{ defer func() { if err := recover(); err != nil { fmt.Println("Panic recover, Err =", err) } }() return a / b } ``` 此时,我们运行程序,控制台输出如下: ![](https://haicoder.net/uploads/pic/notes/golang/22_Go%E8%AF%AD%E8%A8%80panic%20recover.png) 在主函数里面,子协程发生了 panic,并且使用了 recover,不影响主函数的继续执行。 ## Golang panic recover总结 golang 中的 defer 的使用可以总结为,如果 panic 和 recover 发生在同一个协程,那么 recover 是可以捕获的,如果 panic 和 recover 发生在不同的协程,那么 recover 是不可以捕获的。 原文地址:**[嗨客网](https://haicoder.net/note/golang/golang-panic-recover.html)** 更多文章,可以关注下方公众号: ![嗨客网](https://haicoder.net/quickmark.png)

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1149 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传