• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    go 异常处理panic和recover的简单实践

    发布者: 怀卉1097 | 发布时间: 2025-8-14 12:34| 查看数: 28| 评论数: 0|帖子模式

    panic 和 recover

    当然能触发程序宕机退出的,也可以是我们自己,比如经过检查判断,当前环境无法达到我们程序进行的预期条件时(比如一个服务指定监听端口被其他程序占用),可以手动触发 panic,让程序退出停止运行。

    1. 触发panic

    手动触发宕机,是非常简单的一件事,只需要调用 panic 这个内置函数即可,就像这样子
    1. package main

    2. func main() {
    3.     panic("crash")
    4. }
    复制代码
    运行结果:
    1. panic: crash

    2. goroutine 1 [running]:
    3. main.main()
    4.         d:/Goworks/src/尚硅谷/异常处理/demo01.go:4 +0x25
    5. exit status 2
    复制代码
    2. 捕获 panic

    发生了异常,有时候就得捕获,就像 Python 中的
    1. except
    复制代码
    一样,那 Golang 中是如何做到的呢?
    这就不得不引出另外一个内建函数 –
    1. recover
    复制代码
    ,它可以让程序在发生宕机后起生回生。
    但是 recover 的使用,有一个条件,就是它必须在 defer 函数中才能生效,其他作用域下,它是不工作的。
    这是一个简单的例子
    1. package main

    2. import "fmt"

    3. func set_data(x int) {
    4.     defer func() {
    5.         // recover() 可以将捕获到的panic信息打印
    6.         if err := recover(); err != nil {
    7.             fmt.Println(err)
    8.         }
    9.     }()

    10.     // 故意制造数组越界,触发 panic
    11.     var arr [10]int
    12.     arr[x] = 88
    13. }

    14. func main() {
    15.     set_data(20)

    16.     // 如果能执行到这句,说明panic被捕获了
    17.     // 后续的程序能继续运行
    18.     fmt.Println("everything is ok")
    19. }
    复制代码
    运行结果:
    捕获到panic后正常运行。
    1. runtime error: index out of range [20] with length 10
    2. everything is ok
    复制代码
    3. 无法跨协程

    从上面的例子,可以看到,即使 panic 会导致整个程序退出,但在退出前,若有 defer 延迟函数,还是得执行完 defer 。
    但是这个 defer 在多个协程之间是没有效果,在子协程里触发 panic,只能触发自己协程内的 defer,而不能调用 main 协程里的 defer 函数的。
    来做个实验就知道了
    1. package main

    2. import (
    3.     "fmt"
    4.     "time"
    5. )

    6. func main() {
    7.     // 这个 defer 并不会执行
    8.     defer fmt.Println("in main")

    9.     go func() {
    10.         defer println("in goroutine")
    11.                 // 这个panic就会终止程序
    12.                 // 在这终止了外面的defer也不会执行
    13.         panic("")
    14.     }()

    15.     time.Sleep(2 * time.Second)
    16. }
    复制代码
    输出如下,并没有执行defer fmt.Println(“in main”)
    1. in goroutine
    2. panic:

    3. goroutine 19 [running]:
    4. main.main.func1()
    5.         d:/Goworks/src/尚硅谷/异常处理/demo03.go:14 +0x3e
    6. created by main.main in goroutine 1
    7.         d:/Goworks/src/尚硅谷/异常处理/demo03.go:12 +0x59
    8. exit status 2
    复制代码
    4. 总结

    Golang 异常的抛出与捕获,依赖两个内置函数:

    • panic:抛出异常,使程序崩溃
    • recover:捕获异常,恢复程序或做收尾工作(通常来说,不应该对进入 panic 宕机的程序做任何处理,但有时,需要我们可以从宕机中恢复,至少我们可以在程序崩溃前,做一些操作,举个例子,当 web 服务器遇到不可预料的严重问题时,在崩溃前应该将所有的连接关闭,如果不做任何处理,会使得客户端一直处于等待状态,如果 web 服务器还在开发阶段,服务器甚至可以将异常信息反馈到客户端,帮助调试。)
    revocer 调用后,抛出的 panic 将会在此处终结,不会再外抛,但是 recover,并不能任意使用,它有强制要求,必须得在 defer 下才能发挥用途。
    到此这篇关于go 异常处理panic和recover的简单实践的文章就介绍到这了,更多相关go 异常处理panic和recover内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作!

    最新评论

    浏览过的版块

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表