recover和panic的使用注意事项

panic & recover 作用范围的:

  • recover 只有在 defer 中调用才会生效;
  • panic 允许在 defer 中嵌套多次调用;
  • panic 只会对当前 Goroutine 的 defer 有效

恢复异常代码

defer func() {
  if err := recover(); err !=nil{
   fmt.Println(err)
  }
 }()

runtime 中有哪些坑?

panic 我们在实现业务的时候是不推荐使用的,但是并不代表 runtime 里面不会用到,对于不了解 Go 底层实现的新人来说,这无疑是挖了一堆深坑。如果不熟悉这些坑,是不可能写出健壮的 Go 代码。

下面我将 runtime 中的异常分一下类,有一些异常是 recover 也捕获不到的,有一些是正常的 panic 可以被捕获到。

无法捕获的异常

内存溢出

复制代码
func main() {
 defer errorHandler()
 _ = make([]int64, 1<<40)
 fmt.Println("can recover")
}

func errorHandler() {
 if r := recover(); r != nil {
  fmt.Println(r)
 }
}
复制代码

map 并发读写

复制代码
func main() {
 defer errorHandler()
 m := map[string]int{}

 go func() {
  for {
   m["x"] = 1
  }
 }()
 for {
  _ = m["x"]
 }
}

func errorHandler() {
 if r := recover(); r != nil {
  fmt.Println(r)
 }
}
复制代码

能够被捕获的异常

数组 ( slice ) 下标越界

复制代码
func foo(){
 defer func() {
  if r := recover(); r != nil {
   fmt.Println(r)
  }
 }()
 var bar = []int{1}
 fmt.Println(bar[1])
}

func main(){ 
 foo()
 fmt.Println("exit")
}
复制代码

空指针异常

复制代码
func foo(){
 defer func() {
  if r := recover(); r != nil {
   fmt.Println(r)
  }
 }()
 var bar *int
 fmt.Println(*bar)
}

func main(){
 foo()
 fmt.Println("exit")
}
复制代码

 

posted @   国泰君安  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示