【Go】 探索 Go 语言的内建函数 recover


山水间歌声回荡

回荡思念的滚烫

去年的家书两行

读来又热了眼眶

云水边静沐暖阳

烟波里久违的故乡

别来无恙

你在心上

🎵 张靓颖/张杰《燕归巢》


在 Go 语言中,recover 是一个内建函数,用于从 panic 状态中恢复执行。recover 只能在延迟函数(defer)中使用,如果没有 panic 被触发,recover 返回 nil。本文将详细介绍 recover 函数的使用场景和示例。

recover 函数的基本语法

recover 函数的基本语法如下:

go 复制代码
recover() interface{}

使用 recover 恢复 panic

recover 函数通常与 defer 和 panic 一起使用,以防止程序崩溃并提供恢复机制。

基本示例

go 复制代码
package main

import "fmt"

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获到恐慌:", r)
        }
    }()
    
    fmt.Println("程序开始")
    panic("发生了不可恢复的错误")
    fmt.Println("程序结束") // 不会执行
}

在这个例子中,当 panic 触发时,recover 函数捕获恐慌信息,使得程序不会崩溃,并打印 "捕获到恐慌: 发生了不可恢复的错误"。

实际应用中的 recover 使用场景

防止程序崩溃

在一些关键的地方使用 recover 可以防止整个程序崩溃,特别是在服务器程序中。

go 复制代码
package main

import "fmt"

func main() {
    safeFunction()
    fmt.Println("程序继续执行")
}

func safeFunction() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获到恐慌:", r)
        }
    }()
    
    panic("一些错误")
    fmt.Println("不会执行到这里")
}
多个 defer 的 recover 使用

多个 defer 的场景中,只有最先被推入栈的 defer 可以捕获 panic。

go 复制代码
package main

import "fmt"

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("第一个 defer 捕获到恐慌:", r)
        }
    }()
    
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("第二个 defer 捕获到恐慌:", r)
        }
    }()
    
    panic("触发恐慌")
}

在这个例子中,第二个 defer 中的 recover 无法捕获 panic,因为 panic 被第一个 defer 捕获并处理。

使用 recover 的注意事项

  • 只能在 defer 中使用:recover 必须在延迟函数中使用,否则无法捕获到 panic。
  • 理解 panic 和 recover 的关系:panic 会停止当前函数的执行并开始逐层向上清理调用栈,直到遇到 defer 中的 recover。
  • 适度使用:panic 和 recover 应该用于处理不可恢复的错误,不应滥用来控制正常的程序流程。

示例代码

以下是一个综合示例,展示了如何在不同情况下使用 recover 函数:

go 复制代码
package main

import "fmt"

func main() {
    // 示例 1: 基本使用
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获到恐慌:", r)
        }
    }()
    
    fmt.Println("程序开始")
    panic("发生了不可恢复的错误")
    fmt.Println("程序结束") // 不会执行

    // 示例 2: 防止程序崩溃
    safeFunction()
    fmt.Println("程序继续执行")

    // 示例 3: 多个 defer
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("第一个 defer 捕获到恐慌:", r)
        }
    }()
    
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("第二个 defer 捕获到恐慌:", r)
        }
    }()
    
    panic("触发恐慌")
}

func safeFunction() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获到恐慌:", r)
        }
    }()
    
    panic("一些错误")
    fmt.Println("不会执行到这里")
}

总结

recover 是 Go 语言中的一个强大工具,用于从 panic 状态中恢复执行。理解和正确使用 recover 函数,可以显著提高代码的健壮性和容错能力。希望这篇博客能帮助你更好地理解和使用 Go 语言中的 recover 函数,让你的编程之旅更加顺畅。

相关推荐
大傻^1 小时前
Spring AI Alibaba Function Calling:外部工具集成与业务函数注册
java·人工智能·后端·spring·springai·springaialibaba
傻啦嘿哟1 小时前
Python 操作 Excel 条件格式指南
开发语言·python·excel
逆境不可逃2 小时前
LeetCode 热题 100 之 33. 搜索旋转排序数组 153. 寻找旋转排序数组中的最小值 4. 寻找两个正序数组的中位数
java·开发语言·数据结构·算法·leetcode·职场和发展
码界奇点2 小时前
基于Spring Boot的医院药品管理系统设计与实现
java·spring boot·后端·车载系统·毕业设计·源代码管理
小旭95272 小时前
Spring MVC :从入门到精通(下)
java·后端·spring·mvc
星空下的月光影子2 小时前
易语言开发从入门到精通:进阶篇·数据处理与分析自动化·高频刚需手工转自动场景全覆盖
开发语言
林夕sama2 小时前
多线程基础(四)
java·开发语言
Yang-Never2 小时前
ADB ->adb shell perfetto 抓取 trace 指令
android·开发语言·adb·android studio
小鸡吃米…2 小时前
Python 网络爬虫 —— 环境设置
开发语言·爬虫·python