章节

12.2 panic 中断程序

本篇学习 panic 的中断行为,并能区分普通错误与不可继续执行的严重问题。

panic 中断程序

概念说明

panic 表示程序遇到了无法继续执行的严重问题。
触发 panic 后,当前函数会停止正常流程,并开始向上展开调用栈。

普通业务错误应优先返回 error
panic 更适合表示程序员错误、不可恢复状态或初始化阶段的致命问题。

语法/规则

  1. 使用 panic(value) 主动触发 panic。
  2. 数组越界、空指针解引用等运行时错误也会触发 panic。
  3. panic 会执行当前 goroutine 中已经注册的 defer
  4. 没有被 recover 捕获时,程序会打印 panic 信息并退出。
  5. 不要把 panic 当成普通流程控制。

panic 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

func mustPositive(count int) {
	if count <= 0 {
		panic("count must be positive")
	}
}

func main() {
	mustPositive(0)
}

关键输出:

1
panic: count must be positive

上面的例子更偏向语法演示。
下面这个场景更能体现 panic 什么时候该用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

type Config struct {
	DBURL string
}

func mustLoadConfig(cfg Config) {
	if cfg.DBURL == "" {
		// 启动必须依赖的配置缺失,程序已经无法继续正常工作
		panic("missing DB_URL")
	}
}

func main() {
	cfg := Config{} // 假设启动时没有读取到数据库配置
	mustLoadConfig(cfg)

	// 不会执行到这里,因为 panic 已经中断了当前程序
	fmt.Println("server started")
}

这个例子想说明:

  1. 用户输入错误、参数校验失败,通常返回 error 更合适。
  2. 像“启动必需配置缺失”这种程序根本无法继续运行的情况,才更适合 panic

常见错误

  1. 把用户输入错误、校验失败等普通业务问题都写成 panic
  2. 以为 panic 后面的普通语句还会继续执行,实际当前正常流程会被打断。
  3. 忘记 panic 只影响当前 goroutine 的调用栈,跨 goroutine 需要在各自内部处理。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字