Go语言-panic异常(go语言error)

1.panic是什么?

panic 是 Go 语言用于处理运行时严重错误的机制。当 panic 发生时,程序会立即停止执行,并开始回溯(unwind)调用栈,执行所有已注册的 defer 语句,最后终止程序。


2.panic的触发方式

panic 可以通过显式调用 panic() 触发,也可能由于运行时错误(如数组越界、空指针访问等)自动触发。

(1) 显式调用panic

可以在代码中手动调用 panic,用于表示程序遇到了无法继续执行的错误。

示例:

package main

import "fmt"

func main() {
    fmt.Println("程序开始")
    panic("发生了严重错误!")
    fmt.Println("这行代码不会执行")
}

输出:

程序开始
panic: 发生了严重错误!

goroutine 1 [running]:
main.main()
    /tmp/sandbox389323384/prog.go:6 +0x40

可以看到 panic 触发后,程序终止,并打印错误信息。


(2) 运行时异常触发panic

有些错误会导致 Go 语言自动触发 panic,例如:

  • 数组越界
  • 空指针访问
  • 除数为零
  • 关闭已关闭的通道

示例:

package main

import "fmt"

func main() {
    var arr = []int{1, 2, 3}
    fmt.Println(arr[5]) // 数组越界,触发 panic
}

输出:

panic: runtime error: index out of range [5] with length 3

程序崩溃,并提示数组越界错误


3.panic的执行流程

当 panic 触发时,Go 语言会执行以下步骤:

  1. 立即停止当前函数的执行。
  2. 回溯调用栈,依次执行所有 defer 语句(如果有)。
  3. 如果 panic 没有被拦截,程序最终崩溃,并打印 panic 信息及调用栈。

示例:

package main

import "fmt"

func functionA() {
    fmt.Println("进入 functionA")
    panic("functionA 发生错误")
    fmt.Println("离开 functionA") // 这行不会执行
}

func main() {
    fmt.Println("程序开始")
    functionA()
    fmt.Println("程序结束") // 这行不会执行
}

输出:

程序开始
进入 functionA
panic: functionA 发生错误

goroutine 1 [running]:
main.functionA()
    /tmp/sandbox389323384/prog.go:6 +0x40
main.main()
    /tmp/sandbox389323384/prog.go:12 +0x40

panic 触发后,functionA 立即终止,main 也终止,并打印调用栈信息。


4.panic的使用场景

panic 适用于发生不可恢复的严重错误,如:

  • 代码逻辑不应该触发的情况(如非法状态)
  • 程序初始化失败(如关键资源不可用)
  • 标准库 API 设计(如 log.Panic)

示例:初始化失败时使用 panic

package main

import "fmt"

func initConfig() {
    panic("配置文件损坏,无法启动")
}

func main() {
    fmt.Println("启动程序")
    initConfig() // 触发 panic
    fmt.Println("这行不会执行")
}

5.panic与os.Exit的区别

panic 和 os.Exit 都能终止程序,但有以下不同:

特性

panic

os.Exit

是否执行 defer

是否回溯调用栈

是否打印错误信息

示例:

package main

import (
    "fmt"
    "os"
)

func main() {
    defer fmt.Println("defer 执行")
    
    // os.Exit(1) // 直接退出,defer 不会执行
    panic("触发 panic") // 触发 panic,defer 仍然会执行
}

如果使用 os.Exit(1),defer 语句不会执行,而 panic 触发后仍然会执行 defer。


6. 总结

  • panic 适用于发生不可恢复的严重错误。
  • panic 触发后,会停止当前函数,并回溯调用栈,执行 defer,最终终止程序。
  • Go 语言会自动触发 panic(如数组越界、空指针等)。
  • panic 和 os.Exit 都能终止程序,但 panic 会执行 defer 并打印错误信息。
原文链接:,转发请注明来源!