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")
}
相关推荐
言乐68 小时前
Python游戏水平测试辅助系统
开发语言·python·游戏·django·pygame
东风破_14 小时前
ESLint 是什么?为什么你的项目需要它?
前端·后端·代码规范
嘻哈∠※15 小时前
0061基于 SpringBoot 的投稿与稿件处理系统设计与实现
java·spring boot·后端
WWJA王文举15 小时前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
卷无止境15 小时前
在 awesome-fastapi 里,哪些库值得一看?
后端·python
zhanghaha131415 小时前
Python进阶教程:6_JSON 数据解析 —— 新手完全指南
开发语言·python·json
圣殿骑士-Khtangc16 小时前
Go字符串高效拼接性能对比与底层原理分析
服务器·前端·golang
卷无止境16 小时前
FastAPI 的Admin面板生态
后端·python
qq_4480111616 小时前
C语言中的动态内存分配
c语言·开发语言·php
汉字萌萌哒17 小时前
2024CSP-J入门级C++真题详解
开发语言·c++