defer/panic/recover
defer 延迟执行(LIFO)、panic 恐慌、recover 捕获、何时用
defer/panic/recover
defer 保证函数退出前执行(类似 finally 但更灵活),panic 是"不可恢复的错误",recover 捕获 panic。
学完本章你将: 掌握 defer LIFO、panic/recover、典型使用场景。
defer —— 延迟执行
go
package main
import "fmt"
func main() {
defer fmt.Println("第一") // LIFO:最后声明的最先执行
defer fmt.Println("第二")
defer fmt.Println("第三")
fmt.Println("开始")
}
// 输出:开始 → 第三 → 第二 → 第一
defer 经典场景
go
// 1. 关闭文件
func readFile(path string) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close() // 保证文件一定关闭
// ... 使用 f ...
return nil
}
// 2. 释放锁
mu.Lock()
defer mu.Unlock()
// 3. 记录耗时
func trackTime(name string) func() {
start := time.Now()
return func() {
fmt.Printf("%s 耗时 %v\n", name, time.Since(start))
}
}
defer trackTime("myFunc")()
panic / recover
go
// panic = 程序遇到无法继续的错误
func mustBePositive(n int) {
if n < 0 {
panic("n 不能为负数!")
}
}
// recover = 捕获 panic(只在 defer 中有效)
func safeCall() {
defer func() {
if r := recover(); r != nil {
fmt.Println("捕获到 panic:", r)
}
}()
mustBePositive(-1) // 会 panic,但被 recover 捕获
}
⚠️ panic 应该少用。 Go 的惯例是返回 error,只在真正不可恢复的情况下用 panic(如程序初始化失败)。