太狠了!原来panic可以直接干掉程序

简介: 太狠了!原来panic可以直接干掉程序

/ Go 语言 panic 详解 /

Go 语言中 panic 可以导致程序异常终止运行。本文将详细介绍 panic 的触发条件、运行机制以及如何处理 panic 导致的宕机错误。本文主要内容

  1. panic 基本介绍
  2. 直接调用 panic
  3. panic 触发条件
  4. panic 流程
  5. defer 函数依然运行
  6. recover 捕获 panic
  7. panic vs os.Exit
  8. 避免滥用 panic

1

 

一、panic 基本介绍

panic 内置函数可以直接触发程序运行时异常:

func panic(interface{})

调用 panic 会造成当前程序崩溃退出。

2

 

二、直接调用 panic

直接调用 panic 函数会导致程序宕机:

func main() {
  panic("crash") 
}

运行时会输出参数"crash",然后程序异常退出。

3

 

三、panic 触发条件

以下情况会触发 panic:

  • 直接调用 panic 函数
  • 数组索引越界
  • 空指针引用
  • 类型断言失败

这些都会造成 panic 异常。

4

 

四、panic 流程

panic 被触发后会引发以下流程:

  1. 当前 goroutine 暂停运行
  2. 当前 goroutine 进行 defer 的清理工作
  3. 沿调用堆栈向上回溯,直到遇到 recover
  4. 如果整个程序没有 recover,则程序退出

5

 

五、defer 函数依然运行

即使发生了 panic,但 defer 定义的函数依然会执行:

func main() {
  defer fmt.Println("cleaned")
  panic("crash")
}

输出:

cleaned
panic: crash

defer 可以做资源清理工作。

6

 

六、recover 捕获 panic

可以通过 recover 在 defer 内部捕获 panic:

func main() {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println(err) 
    }
  }()
  panic("bad end")
}

recover 可以中断 panic 流程,捕获错误信息。

7

 

七、panic vs os.Exit

os.Exit 也可以退出程序,两者区别:

  • os.Exit 直接退出,不输出长堆栈信息
  • panic 会输出明确的 panic 堆栈信息

8

 

八、避免滥用 panic

正确的错误处理原则:

  • panic 仅用于致命错误
  • 可恢复错误使用 error
  • 不要过度使用 panic

9

 

总结

panic 可以快速退出程序,但不应滥用。使用 recover 捕获和处理 panic,可以使程序更加健壮。


目录
相关文章
|
7月前
|
存储 Go
No.19 干!系统崩溃,又空指针panic?(一)
No.19 干!系统崩溃,又空指针panic?
|
7月前
|
安全 Go
No.19 干!系统崩溃,又空指针panic?(二)
No.19 干!系统崩溃,又空指针panic?
|
7月前
|
Go
No.19 干!系统崩溃,又空指针panic?(三)
No.19 干!系统崩溃,又空指针panic?
|
10月前
|
Go
goroutine传参panic,原因在源码中找到了
goroutine传参panic,原因在源码中找到了
|
11月前
|
传感器 Windows
关于单片机编程里面调用sprintf死机的解决方法及原因分析
关于单片机编程里面调用sprintf死机的解决方法及原因分析
340 0
关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
|
存储 编译器 C语言
Win知识 - 程序是怎样跑起来的——函数调用机制
Win知识 - 程序是怎样跑起来的——函数调用机制
81 0
Win知识 - 程序是怎样跑起来的——函数调用机制
|
网络协议 小程序 NoSQL
如何避免 Go 命令行执行产生“孤儿”进程?
在 Go 程序当中,如果我们要执行命令时,通常会使用 exec.Command ,也比较好用,通常状况下,可以达到我们的目的,如果我们逻辑当中,需要终止这个进程,则可以快速使用 cmd.Process.Kill() 方法来结束进程。但当我们要执行的命令会启动其他子进程来操作的时候,会发生什么情况?
如何避免 Go 命令行执行产生“孤儿”进程?