Files
go-basics/stage02-control-flow/04-defer/README.md
T

99 lines
1.7 KiB
Markdown
Raw Normal View History

2026-03-13 23:54:07 +08:00
# 04-defer - defer机制
## 知识点讲解
### defer基本语法
`defer`语句会将函数调用推迟到当前函数返回之前执行。
```go
func example() {
defer fmt.Println("最后执行")
fmt.Println("先执行")
}
// 输出:
// 先执行
// 最后执行
```
### defer的执行顺序
多个defer语句按照**后进先出(LIFO)**的顺序执行。
```go
func example() {
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
}
// 输出:
// 3
// 2
// 1
```
### defer的参数求值
defer语句中的函数参数在defer声明时就被求值(立即求值),而不是在实际执行时。
```go
func example() {
i := 0
defer fmt.Println(i) // i=0 在此时被求值
i = 10
}
// 输出: 0 (而不是10)
```
### defer修改返回值
使用具名返回值时,defer可以修改返回值。
```go
func example() (result int) {
defer func() {
result = 100 // 修改返回值
}()
return 50
}
// 返回: 100
```
### defer的常见用途
1. **关闭资源**:
```go
file, err := os.Open("file.txt")
if err != nil {
return err
}
defer file.Close() // 确保文件被关闭
```
2. **释放锁**:
```go
mutex.Lock()
defer mutex.Unlock() // 确保锁被释放
```
3. **恢复panic**:
```go
defer func() {
if r := recover(); r != nil {
fmt.Println("恢复:", r)
}
}()
```
## 学习目标
完成本练习后,你将:
- ✅ 理解defer的执行时机
- ✅ 掌握defer的执行顺序(LIFO)
- ✅ 了解defer参数的立即求值特性
- ✅ 学会defer的常见应用场景
## 练习说明
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。