文章目录
零、概述
| 关键字/函数 | 作用描述 |
|---|---|
defer |
延迟执行函数,用于资源释放、日志记录等,按LIFO顺序执行 |
panic |
触发异常,终止当前协程正常执行,可显式调用或由运行时错误触发 |
recover |
在defer中捕获panic,恢复程序执行,避免崩溃 |
| 执行顺序 | defer → return → panic(若未捕获) |
| 最佳实践 | defer用于资源管理,panic/recover用于不可恢复的严重错误处理 |
注意事项:
- defer的性能影响
- 每个
defer会创建一个栈帧,过多使用可能影响性能(尤其在高频调用的函数中)。- 建议仅在必要场景(如资源释放)中使用
defer,避免滥用。- panic的合理使用
- 不建议在业务逻辑中滥用
panic,应优先使用多返回值(如(result, error))处理可预期的错误。- 推荐场景:处理不可恢复的严重错误(如配置文件缺失、数据库连接失败)。
- recover的作用范围
recover仅能捕获当前协程的panic,无法跨协程捕获(如其他goroutine中的panic)。- 跨协程异常处理需通过通道(
channel)传递错误。
一、defer关键字:延迟执行机制
1. 基本原理
核心特性
- 独立的defer栈,延迟执行:
defer修饰的函数或语句会在当前函数即将退出时执行(包括正常返回、panic异常或提前return)。 - 栈存储:多个
defer按**后进先出(LIFO)**顺序执行,先声明的后执行。 - 值拷贝:
defer语句中的参数在声明时立即求值并拷贝,后续修改不影响其值。
defer的作用
一般用来做善后操作,例如清理垃圾、释放资源,无论是否报错都执行defer对象。另一方面,defer可以让这些善后操作的语句和开始语句放在一起,无论在可读性上还是安全性上都很有改善,毕竟写完开始语句就可以直接写defer语句,永远也不会忘记关闭、善后等操作
执行顺序示例
func deferOrder() {
fmt.Println("开始执行")
defer fmt.Println(" defer 1") // 压栈顺序:1 → 2 → 3
defer fmt.Println(" defer 2")
defer fmt.Println(" defer 3")
fmt.Println("执行结束") // 先于 defer 执行
}
// 输出:
// 开始执行
// 执行结束
// defer 3 (最后压栈,最先执行)
// defer 2
// defer 1
2. defer下变量的作用域
(1)值拷贝机制
func deferValueCopy() {
x := 10
defer fmt.Println("defer值拷贝:", x) // 声明时拷贝x的值(10)
x = 20 // 修改不影响 defer 中的值
fmt

最低0.47元/天 解锁文章
1974

被折叠的 条评论
为什么被折叠?



