GO语言延迟函数defer用法分析

本文介绍了Golang中defer关键字的基本概念及使用方式,并通过代码示例展示了defer的执行顺序及其在资源管理和异常处理中的应用。

defer 在声明时不会立即执行,而是在函数 return 后,再按照 FILO (先进后出)的原则依次执行每一个 defer,一般用于异常处理、释放资源、清理数据、记录日志等。这有点像面向对象语言的析构函数,优雅又简洁,是 Golang 的亮点之一。

代码1:了解 defer 的执行顺序

package main
import "fmt"
func fn(n int) int {
 defer func() {
  n++
  fmt.Println("3st:", n)
 }()
 defer func() {
  n++
  fmt.Println("2st:", n)
 }()
 defer func() {
  n++
  fmt.Println("1st:", n)
 }()
 return n //没有做任何事情
}
func main() {
 fmt.Println("函数返回值:", fn(0))
}
输出:
1st: 1
2st: 2
3st: 3
函数返回值: 0

代码2:经典应用实例

func CopyFile(dst, src string) (w int64, err error) {
 srcFile, err := os.Open(src)
 if err != nil {
  return
 }
 defer srcFile.Close() //每次申请资源时,请习惯立即申请一个 defer 关闭资源,这样就不会忘记释放资源了
 dstFile, err := os.Create(dst)
 if err != nil {
  return
 }
 defer dstFile.Close()
 return io.Copy(dstFile, srcFile)
}

defer 还有一个重要的特性,就是即便函数抛出了异常,也会被执行的。 这样就不会因程序出现了错误,而导致资源不会释放了。

### 使用方法 Go 语言提供了 `defer` 关键字,可以注册多个延迟调用,这些调用以先进后出(FILO)的顺序在函数返回前被执行,有点类似 Java 语言中异常处理里的 `finally` 子句。`defer` 语句会立刻计算参数,但延迟函数体的执行 [^4][^5]。 示例代码如下: ```go package main import "fmt" func main() { defer fmt.Println("world") fmt.Println("hello") } ``` 上述代码会先输出 `hello`,再输出 `world`。另一个例子: ```go package main func main() { // 先进后出 defer func() { println("first") }() defer func() { println("second") }() println("function body") } ``` 该代码的输出结果为: ``` function body second first ``` ### 原理 从底层来看,`defer` 有“注册 - 执行”的全生命周期。`defer` 语句会在当前函数栈帧上创建一个 `defer` 结构体来记录要执行的函数和相关参数,这个过程就是“注册”。而在函数返回前,会按照先进后出的顺序依次执行这些 `defer` 函数,这就是“执行” [^2]。 ### 应用场景 - **资源释放**:常用于保证一些资源最终一定能够得到回收和释放。例如文件操作时,使用 `defer` 确保文件在函数结束时关闭: ```go package main import ( "fmt" "os" ) func main() { filename := "test.txt" f, err := os.Open(filename) if err != nil { panic(err) } if f != nil { defer f.Close() } // 对文件进行操作 fmt.Println("文件操作完成") } ``` - **锁的释放**:在使用互斥锁时,使用 `defer` 可以确保锁在函数结束时被释放,避免死锁: ```go package main import ( "fmt" "sync" ) var ( mu sync.Mutex count int ) func increment() { mu.Lock() defer mu.Unlock() count++ fmt.Println("Count:", count) } func main() { increment() } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值