golang特性1

本文介绍了Go语言中defer和recover的关键特性,如何用于资源释放、异常捕获以及在处理panic时的错误恢复,强调了它们在避免资源泄漏和保证程序健壮性方面的作用。
摘要由CSDN通过智能技术生成

golang特性

defer、recover异常捕获和处理

应用场景

1. 资源释放

  • 文件操作:在打开文件后,使用 defer 关闭文件句柄,确保文件在函数退出时被关闭,避免资源泄漏。
  • 数据库连接:在打开数据库连接后,使用 defer 关闭数据库连接,确保数据库连接在函数退出时被关闭,防止数据库连接泄漏。
  • 锁释放:在加锁后,使用 defer 释放锁,确保在函数退出时锁被正确释放,避免死锁情况。

2. 异常捕获和处理

  • 错误恢复:使用 defer 和 recover 捕 panic,并进行错误处理。在程序可能发生致命错误但不想使程序终止的情况下,可以使用 recover 恢复程序的执行,进行必要的错误处理后继续执行。

  • 错误记录:在一些关键任务中,可能不想让程序崩溃,但又想记录异常情况。通过使用 defer 和 recover,可以在出现 panic
    时记录错误信息,然后程序可以继续执行。

defer

defer 是 Go 语言中的一个关键字,用于延迟执行函数调用。被延迟执行的函数会在包含 defer 语句的函数返回之前执行,无论函数是正常返回还是发生了 panic。这使得 defer 可以用于一些清理操作,例如关闭文件、释放资源等。

  • defer 关键词用来声明一个延迟调用函数,该函数可以是匿名函数也可以是具名函数
  • defer延迟函数执行时间(位置),方法return之后,返回参数到调用方法之前
  • defer 延迟函数可以在方法返回之后改变函数的返回值在方法结束(正常返回,异常结束)都会去调用
  • defer声明的延迟函数,可以有效避免因异常导致的资源无法释放的问题 可以指定多个 defer延迟函数,多个延时函数执行顺序为后进先出
  • defer 通常用于资源释放、异常捕获等场景,例如:关闭连接,关闭文件等
  • defer 与recover 配合可以实现异常捕获与处理逻辑
  • 不建议在for循环中使用defer
package main

import "fmt"

func main() {
    for i := 0; i < 3; i++ {
        defer fmt.Println("Deferred call in loop:", i)
    }
    fmt.Println("Loop ended")
}

Loop ended
Deferred call in loop: 2
Deferred call in loop: 1
Deferred call in loop: 0

defer 语句在循环结束后才执行,而且执行顺序是后进先出的。所以在循环中使用 defer 时要谨慎,确保不会导致不必要的资源浪费或不正确的行为。

defer 的典型用途包括:

关闭文件或数据库连接等资源释放
在函数返回之前记录日志信息
在发生异常时执行清理操作
在函数调用前后进行计时或性能分析等操作

recover

recover 是一个内建函数,用于从 panic 中恢复,并返回导致 panic 的值。它通常与 defer 语句一起使用,在发生 panic 时捕获异常,然后进行必要的处理。

  • Go语言的内建函数,可以让进入宕机流程中的 goroutine 恢复过来
  • recover 仅在延迟函数 defer 中有效,在正常的执行过程中,调用 recover 会返回 nil 并且没有其他任何效果
  • 如果当前的 goroutine 出现panic,调用 recover 可以捕获到 panic 的输入值,并且恢复正常的执行
package main

import "fmt"

func recoverDemo() {
    if r := recover(); r != nil {
        fmt.Println("Recovered:", r)
    }
}

func causePanic() {
    defer recoverDemo() // 在panic发生后执行recoverDemo函数
    fmt.Println("Start panic")
    panic("panic occurred")
    fmt.Println("End panic") // 这行代码不会被执行
}

func main() {
    causePanic()
    fmt.Println("Program continues") // 虽然有panic,但由于recover已经处理了,所以程序继续执行
}

输出结果

Start panic
Recovered: panic occurred
Program continues

当 causePanic 函数调用 panic 时,程序会发生 panic,但是由于 recoverDemo 函数被 defer 延迟调用,它在 panic 发生后被执行,打印出了 panic 的信息。然后程序继续执行,而不会终止。

panic

panic 是一个内建函数,用于表示程序遇到了一些无法处理的错误或不可恢复的情况,导致程序的执行无法继续下去。当程序遇到 panic 时,它会立即停止当前函数的执行,沿着函数调用栈向上一层层地执行延迟函数(即使用 defer 声明的函数),然后程序终止并打印出 panic 的信息。

  • Go语言的一种异常机制
  • 可通过panic 函数主动抛出异常
  • 发生时停止函数执行:panic 会导致当前函数的执行立即停止,并开始执行 defer 声明的延迟函数。
  • 传播至调用栈:如果当前函数无法处理 panic,它会向调用当前函数的函数传播 panic,直到遇到可以处理 panic 的 recover,或者直到达到最外层的函数,此时程序会终止并打印出 panic 的信息。
  • 通常用于表示致命错误:panic 通常用于表示程序遇到了一些无法恢复的致命错误,例如无效的参数、内存溢出、文件不存在等。
package main

import "fmt"

func main() {
    fmt.Println("Start of main")
    panic("Something went wrong!") // 程序会在这里发生panic
    fmt.Println("End of main") // 这行代码不会被执行
}

当 panic 被调用时,程序会立即停止执行 main 函数,并开始执行 defer 声明的延迟函数(如果有的话),然后打印出 panic 的信息并终止程序。

虽然 panic 可以用于表示程序的错误状态,但通常建议只在遇到无法处理的情况下才使用 panic,而在可以预见和处理的错误情况下使用错误类型进行错误处理。

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值