defer
是 Go 语言中的一个关键字,用于延迟执行某个函数或语句,直到包含它的函数返回时才执行。defer
语句在函数执行结束后(无论是正常返回还是由于 panic
返回)都将执行。
defer 的基本用法
-
延迟执行: 当你在一个函数内调用
defer
语句,后面的语句将被推迟到该函数执行结束时执行。package mainimport "fmt"func main() {defer fmt.Println("这是最后执行的语句")fmt.Println("这是先执行的语句") }
输出:
这是先执行的语句 这是最后执行的语句
-
多个 defer 语句: 如果一个函数中有多个
defer
语句,它们会按照后进先出(LIFO)的顺序执行。package mainimport "fmt"func main() {defer fmt.Println("第一个 defer")defer fmt.Println("第二个 defer")defer fmt.Println("第三个 defer")fmt.Println("主函数中的代码") }
输出:
主函数中的代码 第三个 defer 第二个 defer 第一个 defer
-
传递参数: 在
defer
语句中传递参数时,参数在defer
被调用时就会被评估,而不是在执行时。package mainimport "fmt"func main() {for i := 0; i < 3; i++ {defer fmt.Println(i) // 这里的 i 会被延迟执行} }
输出:
2 1 0
如果在
defer
语句中直接使用i
的值而不是它的引用,结果会是这样的。
defer 的常见用途
-
资源清理:
defer
常用于释放资源,如关闭文件、数据库连接等。这样可以确保即使在函数中发生错误时,资源仍然能被正确释放。package mainimport ("fmt""os" )func main() {file, err := os.Open("example.txt")if err != nil {fmt.Println("打开文件错误:", err)return}defer file.Close() // 确保文件在函数结束时被关闭// 处理文件... }
-
错误处理: 结合
recover
使用,可以处理panic
并进行错误处理。package mainimport "fmt"func recoverFromPanic() {defer func() {if r := recover(); r != nil {fmt.Println("捕获到 panic:", r)}}()panic("发生了错误") // 触发 panic }func main() {recoverFromPanic()fmt.Println("程序继续运行") }
-
函数执行时间测量: 可以使用
defer
来测量函数执行时间。package mainimport ("fmt""time" )func main() {start := time.Now()defer func() {fmt.Println("函数执行时间:", time.Since(start))}()// 模拟耗时操作time.Sleep(2 * time.Second) }
总结
defer
是 Go 语言中一个强大且灵活的工具,适用于资源管理、错误处理和其他需要在函数返回时执