# 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` 验证答案。