defer、panic、recover

1. defer
(1)defer用于将某个方法或语句推迟到当前函数返回的最后一刻执行,一般用于释放某些已分配的资源。函数返回的最后一刻指的是,return语句更新返回值变量之后,函数返回之前,所以defer语句甚至可用于修改函数的返回值(函数头部命名了返回值的情况)。
(2)若defer语句中嵌套了多层函数调用,只是最后一层函数调用才延后执行,其他都按代码执行顺序执行,例如:defer un(trace("b")),先按代码执行顺序执行trace("b"),假设返回值为ret,在函数返回前的最后一刻再执行un(ret)。
(3)defer语句一定会执行,即使发生了panic;defer一定是函数返回的最后一刻才执行,除非遇到panic,才会先执行defer,再执行panic。
(4)若存在多个return分支,且每个return语句之前都需要执行某些同样的操作,则使用defer语句可以避免重复写同样的代码。
(5)当有多个defer行为被注册时,它们会按注册的先后顺序逆序执行(类似栈,后进先出)。

2. panic
(1)Go语言的panic机制类似其他语言的异常,但panic会引起程序的崩溃,一般用于严重错误,大部分错误都应该使用Go语言提供的错误机制,而不是panic。
(2)可使用panic()函数手动触发panic。
(3)当panic发生时,程序会中断运行,并立即执行在当前goroutine中被延迟的所有函数(defer机制),最后程序崩溃,输出错误信息,以及发生panic时的函数调用堆栈跟踪信息,为问题定位提供依据。

3. recover
(1)Go语言提供了内置函数recover(),一般在defer语句中调用,用于捕获panic异常,使程序从panic中回复,并返回panic value。
(2)导致panic异常的函数不会继续运行,但是能正常返回,这意味着调用recover()的函数的上一级调用者可以继续往下执行代码,而不是中断程序运行。
(3)利用recover处理panic时,defer必须在panic之前声明,否则当panic时,recover无法捕获到panic。

4. 一个实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main
 
import (
    "fmt"
)
 
func main() {
    defer func() { fmt.Println(1) }()
    fmt.Println(2)
    defer func() { fmt.Println(3) }()
    defer_call1()
    fmt.Println(4)
}
 
func defer_call1() {
    defer func() { fmt.Println("A") }()
    fmt.Println("B")
    /*
    defer func() {
        fmt.Println("C")
        err := recover()
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println("D")
    }()
    */
    defer func() { fmt.Println("E") }()
    defer_call2()
    fmt.Println("F")
}
 
func defer_call2() {
    defer func() { fmt.Println("a") }()
    defer func() { fmt.Println("b") }()
    defer func() { fmt.Println("c") }()
    fmt.Println("d")
    panic("触发异常1")
    panic("触发异常2")
    fmt.Println("e")
}

(1)直接运行输出:

(2)去掉注释的recover相关代码,运行输出:

 

posted @   疯一样的狼人  阅读(1446)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2017-10-27 Yii2之组件的注册与创建
点击右上角即可分享
微信分享提示