专业的编程技术博客社区

网站首页 > 博客文章 正文

Golang defer的使用(go语言中defer)

baijin 2025-03-17 15:52:59 博客文章 15 ℃ 0 评论

在 Go 语言中,defer 是一个非常强大的关键字,用于延迟执行函数或方法调用。defer 通常用于资源释放、错误处理、日志记录等场景,以确保某些操作在函数返回前被执行。以下是 defer 的使用教程:


一、defer的基本用法

defer 的语法非常简单,只需在函数调用前加上 defer 关键字即可。被 defer 的语句会在 函数返回前 执行,即使函数中途发生错误或提前返回。

示例 1:基本用法

package main

import "fmt"

func main() {
    defer fmt.Println("World") // 这行会在 main 函数返回前执行
    fmt.Println("Hello")
}

输出:

Hello
World

二、defer的执行顺序

如果有多个 defer 语句,它们会以 后进先出(LIFO) 的顺序执行,即最后一个 defer 最先执行。

示例 2:多个defer

package main

import "fmt"

func main() {
    defer fmt.Println("First")
    defer fmt.Println("Second")
    defer fmt.Println("Third")
}

输出:

Third
Second
First

三、defer的常见用途

1. 资源释放

defer 通常用于确保资源(如文件、数据库连接、锁等)在函数退出时被正确释放。

示例 3:文件操作

package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    defer file.Close() // 确保文件关闭

    // 文件操作
    // ...
}

2. 错误处理

defer 可以用于在函数返回前执行一些错误处理操作。

示例 4:错误处理

package main

import "fmt"

func divide(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil { // 捕获 panic
            err = fmt.Errorf("runtime panic: %v", r)
        }
    }()

    if b == 0 {
        panic("division by zero") // 触发 panic
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 0)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Result:", result)
}

输出:

Error: runtime panic: division by zero

3. 日志记录

defer 可以用于在函数退出时记录日志。

示例 5:日志记录

package main

import "fmt"

func main() {
    defer fmt.Println("Function main completed") // 记录函数完成
    fmt.Println("Function main started")
}

输出:

Function main started
Function main completed

四、defer的注意事项

1.defer的参数是立即求值的

defer 语句中的函数参数会在 defer 语句执行时立即求值,而不是在函数返回时。

示例 6:参数求值

package main

import "fmt"

func main() {
    i := 0
    defer fmt.Println("Deferred:", i) // 参数 i 立即求值
    i++
    fmt.Println("Current:", i)
}

输出:

Current: 1
Deferred: 0

2.defer与返回值

如果函数有返回值,defer 可以修改返回值。

示例 7:修改返回值

package main

import "fmt"

func main() {
    fmt.Println("Result:", test())
}

func test() (result int) {
    defer func() {
        result = 100 // 修改返回值
    }()
    return 10
}

输出:

Result: 100

3.defer的性能开销

defer 的使用会引入一定的性能开销,因为它需要在函数返回前执行额外的操作。在性能敏感的场景中,应谨慎使用。


五、总结

defer 是 Go 语言中非常有用的特性,能够简化资源管理和错误处理。通过合理使用 defer,可以提高代码的可读性和健壮性。主要用途包括:

  • 资源释放(如文件关闭、解锁等)。
  • 错误处理和恢复(如捕获 panic)。
  • 日志记录(如记录函数执行时间)。

掌握 defer 的使用技巧,能够让你的 Go 代码更加优雅和高效。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表