Go 语言 panic 和 recover 详解

panic()recover() 是 Go 语言中用于处理错误的两个重要函数。panic() 函数用于中止程序并引发panic,而 recover() 函数用于捕获panic并恢复程序的执行。

什么是panic和recover?

panic

  • panic() 函数用于中止程序并引发panic。
  • panic() 函数可以接收一个参数,该参数将作为panic的原因。
  • 当发生panic时,程序将停止执行,并开始寻找最近的recover调用。
  • 如果找不到recover调用,程序将打印panic的原因并退出。

recover

  • recover() 函数用于捕获panic并恢复程序的执行。
  • recover() 函数可以接收一个参数,该参数将存储panic的原因。
  • 如果在发生panic时调用了recover,程序将继续执行,并且panic的原因将被存储在recover的第一个参数中。
Go 复制代码
func main() {
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println("panic:", err)
        }
    }()

    panic("hello, panic!")
}

panic 的传播

panic 函数会向上传播到调用它的 goroutine。如果 panic 函数没有被捕获,则会一直向上传播,直到遇到 defer 语句中调用的 recover() 函数,或者程序退出。

注意事项

跨协程失效

panicrecover 不能跨协程使用。这意味着在一个协程中发生的panic只能在同一个协程中通过 recover 捕获。如果在一个协程中发生了panic,而在另一个协程中调用了 recover,那么 recover 将无法捕获panic。参考如下代码:

Go 复制代码
func main() {
	defer println("in main")
	go func() {
		defer println("in goroutine")
		panic("")
	}()

	time.Sleep(1 * time.Second)
}

失效的崩溃恢复

如果在一个defer函数中发生了panic,那么该defer函数后面的语句将不会被执行。这意味着在defer函数中使用 recover 来捕获panic是无效的。

Go 复制代码
func main(){
    defer fmt.Println("main....")
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("panic:", err)
		}
	}()

	panic("hello, panic!")
}

嵌套崩溃

嵌套崩溃是指在一个 goroutine 中调用 panic() 函数,然后在 defer 语句中再次调用 panic() 函数。在这种情况下,panic() 函数会从内向外传播,直到程序崩溃。嵌套崩溃可能会导致程序不可用,因此应避免使用。

Go 复制代码
func multiplePanic() {
	defer fmt.Println("in defer")
	defer func() {
		defer func() {
			panic("panic 3")
		}()
		panic("panic 2")
	}()
	panic("panic 1")
}
相关推荐
章豪Mrrey nical6 小时前
前后端分离工作详解Detailed Explanation of Frontend-Backend Separation Work
后端·前端框架·状态模式
小浣熊熊熊熊熊熊熊丶6 小时前
《Effective Java》第25条:限制源文件为单个顶级类
java·开发语言·effective java
啃火龙果的兔子7 小时前
JDK 安装配置
java·开发语言
星哥说事7 小时前
应用程序监控:Java 与 Web 应用的实践
java·开发语言
派大鑫wink7 小时前
【JAVA学习日志】SpringBoot 参数配置:从基础到实战,解锁灵活配置新姿势
java·spring boot·后端
程序员爱钓鱼7 小时前
Node.js 编程实战:文件读写操作
前端·后端·node.js
xUxIAOrUIII7 小时前
【Spring Boot】控制器Controller方法
java·spring boot·后端
moxiaoran57537 小时前
Go语言的范围range
golang
Dolphin_Home7 小时前
从理论到实战:图结构在仓库关联业务中的落地(小白→中级,附完整代码)
java·spring boot·后端·spring cloud·database·广度优先·图搜索算法
等....7 小时前
Miniconda使用
开发语言·python