defer关键字:延迟调用机制-《Go语言实战指南》

简介: Go 语言中的 `defer` 是用于延迟执行函数调用的关键字,广泛应用于资源释放、异常捕获和日志记录等场景。它在函数返回前执行,支持栈式后进先出(LIFO)顺序,参数求值时机为声明时而非执行时。常见用法包括文件关闭、锁解锁及结合 `recover` 处理 panic。尽管高效,频繁使用可能带来性能开销,需谨慎处理。总结而言,`defer` 是构建健壮代码的核心工具之一。

 

defer 是 Go 语言中用于延迟执行函数调用的关键字。它广泛用于资源释放、异常捕获、日志记录等场景,是构建健壮代码的利器。


一、基本语法

defer 函数调用
  • defer 语句会推迟函数的执行,直到包含它的函数执行完毕。
  • • 多个 defer以栈的方式后进先出(LIFO)执行。

示例:

func test() {
    defer fmt.Println("A")
    defer fmt.Println("B")
    fmt.Println("C")
}
test()
// 输出:
// C
// B
// A

二、常见应用场景

1. 资源释放

file, err := os.Open("test.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

打开文件后,使用 defer 确保最终关闭文件,即使中途发生错误也能安全释放资源。


2. 锁的释放

mu.Lock()
defer mu.Unlock()

3. 捕获异常

结合 recover() 使用,优雅处理 panic:

func safe() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获异常:", r)
        }
    }()
    panic("something went wrong")
}
safe()
// 输出:捕获异常: something went wrong

三、参数的求值时机

虽然函数调用被延迟,但参数会立即计算

func test(x int) {
    defer fmt.Println("defer:", x)
    x++
    fmt.Println("normal:", x)
}
test(10)
// 输出:
// normal: 11
// defer: 10

四、defer 的性能影响

  • defer 虽然非常实用,但在高性能敏感代码中频繁使用 defer 可能造成微小开销
  • • Go 1.14 起,defer 性能有显著优化。

五、多个 defer 的执行顺序

func f() {
    for i := 1; i <= 3; i++ {
        defer fmt.Println("defer", i)
    }
}
f()
// 输出:
// defer 3
// defer 2
// defer 1

六、小技巧:修改返回值

defer 可用于修改命名返回值,用于函数退出前调整返回数据。

func demo() (result int) {
    defer func() {
        result += 100
    }()
    return 1
}
fmt.Println(demo()) // 输出 101

七、小结

特性 说明
延迟执行 在函数返回前执行,可用于清理资源
栈顺序 多个 defer 后进先出执行
参数时机 参数立即求值,函数调用延迟执行
常见用途 文件关闭、解锁、恢复 panic 等
返回值控制 可用于修改命名返回值

defer 简洁强大,是写出安全、可维护 Go 代码的重要利器。

 

相关文章
|
26天前
|
Go 调度
GO语言函数的内部运行机制分析
以上就是Go语言中函数的内部运行机制的概述,展示了函数在Go语言编程中如何发挥作用,以及Go如何使用简洁高效的设计,使得代码更简单,更有逻辑性,更易于理解和维护。尽管这些内容深入了一些底层的概念,但我希望通过这种方式,将这些理论知识更生动、更形象地带给你,让你在理解的同时找到编程的乐趣。
45 5
|
2月前
|
存储 算法 物联网
解析局域网内控制电脑机制:基于 Go 语言链表算法的隐秘通信技术探究
数字化办公与物联网蓬勃发展的时代背景下,局域网内计算机控制已成为提升工作效率、达成设备协同管理的重要途径。无论是企业远程办公时的设备统一调度,还是智能家居系统中多设备间的联动控制,高效的数据传输与管理机制均构成实现局域网内计算机控制功能的核心要素。本文将深入探究 Go 语言中的链表数据结构,剖析其在局域网内计算机控制过程中,如何达成数据的有序存储与高效传输,并通过完整的 Go 语言代码示例展示其应用流程。
70 0
|
6月前
|
Go 索引
go语言使用range关键字
go语言使用range关键字
83 7
|
7月前
|
安全 Go 索引
go语言使用 range 关键字
go语言使用 range 关键字
79 3
|
7月前
|
测试技术 Go 索引
go语言使用 range 关键字遍历
go语言使用 range 关键字遍历
92 3
|
7月前
|
存储 安全 Go
Go 语言以其高效的并发编程能力著称,主要依赖于 goroutines 和 channels 两大核心机制
Go 语言以其高效的并发编程能力著称,主要依赖于 goroutines 和 channels 两大核心机制。本文介绍了这两者的概念、用法及如何结合使用,实现任务的高效并发执行与数据的安全传递,强调了并发编程中的注意事项,旨在帮助开发者更好地掌握 Go 语言的并发编程技巧。
102 2
|
7月前
|
存储 算法 Java
Go语言的内存管理机制
【10月更文挑战第25天】Go语言的内存管理机制
133 2
|
10月前
|
存储 编译器 Go
|
10月前
|
存储 Go
掌握 Go 语言的 defer 关键字
掌握 Go 语言的 defer 关键字
|
10月前
|
Go 数据处理