首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >go中的panic和recover

go中的panic和recover

原创
作者头像
浩瀚星河
发布2025-08-07 18:39:51
发布2025-08-07 18:39:51
1450
举报
文章被收录于专栏:golanggolang
  1. panic 是 go 的内置机制,输出严重错误。如果没有恢复程序会打印堆栈,然后退出
  2. recover 也是 go 的内置机制,在当前 goroutine 恢复 panic,返回值为 panic 中的引用信息

注意: recover 一定要与 defer 一起使用,不然 recover 只会返回 nil

示例程序:

代码语言:go
复制
package main

func A() {
	B()
}

func B() {
	C()
}

func C() {
	panic("报错了")
}

func main() {
	A()
}

输出结果:

代码语言:bash
复制
panic: 报错了

goroutine 1 [running]:
main.C(...)
        /code/demo/panic/main.go:12
main.B(...)
        /code/demo/panic/main.go:8
main.A(...)
        /code/demo/panic/main.go:4
main.main()
        /code/demo/panic/main.go:16 +0x25
exit status 2

对应的报错堆栈信息比较清晰

C -> B -> A -> main

最后抛到 main 函数

我们可以在 main 调用 A 函数前使用 defer+recover 对 panic 进行捕获

代码语言:go
复制
defer func() {
    if r := recover(); r != nil {
        fmt.Println("捕获到异常", r)
    }
}()
A()

如上述代码所示,这样就能成功捕获错误,输出如下

代码语言:bash
复制
捕获到异常 报错了

recover 只能用于当前 goroutine,我们来试试在子 goroutine 处 panic,main 函数是否能捕获到

代码语言:go
复制
package main

import (
	"fmt"
	"sync"
)

func doSomething() {
	defer wg.Done()
	fmt.Println("准备panic")
	panic("子goroutine报错了")
}

var wg sync.WaitGroup

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("recover捕获到异常值为:", r)
		}
	}()
	wg.Add(1)
	go doSomething()
	wg.Wait()
	fmt.Println("无法捕获")
}

输出结果:

代码语言:bash
复制
root@pzj:/code/demo/panic# go run main.go
准备panic
panic: 子goroutine报错了

goroutine 6 [running]:
main.doSomething()
        /code/demo/panic/main.go:11 +0x90
created by main.main in goroutine 1
        /code/demo/panic/main.go:18 +0x31
exit status 2

可以看到子 goroutine 直接 panic 了,而主 goroutine 捕获是没有用的,查看输出

发现无法捕获没有输出,说明在子 goroutine panic 后直接就退出了,根本就不会回到 main,所以 recover 只能恢复当前 goroutine 的 panic,无法恢复其他 goroutine 的

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档