当前位置: 首页 > news >正文

【Go 基础篇】Go语言中的defer和recover:优雅处理错误

在这里插入图片描述

Go语言以其简洁、高效和强大的特性受到了开发者的热烈欢迎。在错误处理方面,Go语言提供了一种优雅的机制,即通过deferrecover组合来处理恐慌(panic)错误。本文将详细介绍Go语言中的deferrecover机制,探讨其工作原理和在实际开发中的应用。

前言

在软件开发过程中,错误是难以避免的。Go语言提供了一种称为"恐慌和恢复"(panic and recover)的机制,用于处理运行时错误,以确保程序的稳定性和健壮性。通过巧妙地使用deferrecover,开发者可以在发生错误时进行优雅的处理,避免程序的崩溃,以及将错误信息传递到更高级别的上下文中进行处理。

defer语句的作用

defer是Go语言中的一个关键字,用于延迟执行一个函数调用。无论函数是正常返回还是出现恐慌,defer语句都会被执行。这使得defer非常适合用于清理资源、释放锁、关闭文件等操作,以确保这些操作在函数执行完毕后得到执行。

package mainimport "fmt"func cleanup() {fmt.Println("Cleaning up resources")
}func main() {defer cleanup()fmt.Println("Performing some work...")
}

在上述代码中,无论main函数中的工作是否正常结束,cleanup函数都会在其最后被调用,从而确保资源的清理。

recover函数的作用

recover是Go语言的内置函数,用于从恐慌中恢复并返回一个错误值。它只能在延迟函数(defer语句)内部调用,用于捕获并处理由panic引起的恐慌。如果没有发生恐慌,或者recover不在延迟函数中调用,它会返回nil

package mainimport "fmt"func handlePanic() {if r := recover(); r != nil {fmt.Println("Recovered:", r)}
}func main() {defer handlePanic()panic("Something went wrong!")
}

在上述代码中,当panic引起恐慌时,handlePanic函数会被调用,打印出恐慌的错误信息。这样程序不会崩溃,而是在panic发生后继续执行下去。

deferrecover的结合使用

deferrecover的真正威力在于它们的结合使用。通过在恐慌引起的延迟函数中使用recover,我们可以捕获恐慌,并在程序继续执行之前进行处理。

package mainimport "fmt"func handlePanic() {if r := recover(); r != nil {fmt.Println("Recovered:", r)}
}func performTask() {defer handlePanic()fmt.Println("Performing some task...")panic("Oops! Something went wrong!")fmt.Println("Task completed.")
}func main() {performTask()fmt.Println("Main function continues.")
}

在上述代码中,performTask函数中的恐慌不会导致程序崩溃。相反,它会被handlePanic函数捕获并处理,之后程序会继续执行。

在实际开发中的应用

deferrecover机制在实际开发中非常有用。以下是一些应用场景:

1. 资源清理

在操作系统或网络编程中,资源管理非常重要。通过在函数中使用defer来确保资源的正确释放,即使在出现错误时也不会导致资源泄漏。

package mainimport "fmt"func closeFile(file *File) {fmt.Println("Closing file...")file.Close()
}func main() {file := OpenFile("data.txt")defer closeFile(file)// 使用文件进行操作
}

2. 错误处理

通过结合deferrecover,可以在代码中捕获和处理特定类型的错误,而不会导致整个程序崩溃。

package mainimport "fmt"func divide(a, b int) {defer func() {if r := recover(); r != nil {fmt.Println("Recovered:", r)}}()result := a / bfmt.Println("Result:", result)
}func main() {divide(10, 0)fmt.Println("Main function continues.")
}

3. 日志记录

在程序中插入defer语句,用于记录函数的进入和退出,以及执行时间等信息,有助于调试和性能分析。

package mainimport ("fmt""time"
)func logEnterExit(funcName string) func() {start := time.Now()fmt.Printf("Entering %s\n", funcName)return func() {fmt.Printf("Exiting %s (Time taken: %s)\n", funcName, time.Since(start))}
}func foo() {defer logEnterExit("foo")()fmt.Println("Inside foo()")time.Sleep(time.Second)
}func main() {defer logEnterExit("main")()fmt.Println("Inside main()")foo()
}

总结

Go语言的deferrecover机制为开发者提供了一种优雅处理错误的方式,帮助保持程序的稳定性和可维护性。通过在恐慌引起的延迟函数中使用recover,我们可以捕获错误并在程序继续执行之前进行处理。deferrecover的结合使用,使得我们能够在代码中处理资源清理、错误处理、日志记录等任务,而不会因为出现错误而导致整个程序的崩溃。

在开发中,合理使用deferrecover可以帮助我们避免常见的陷阱和错误,同时提高代码的可读性和可维护性。但需要注意的是,recover只能捕获同一Go协程中的恐慌,不能用于跨协程的错误处理。

总之,Go语言的deferrecover机制为错误处理提供了一种非常强大和灵活的方式,使得我们能够在代码中优雅地处理各种异常情况,确保程序在出现问题时也能保持稳定。通过合理运用这些机制,开发者可以写出更健壮、可靠的Go程序。

相关文章:

【Go 基础篇】Go语言中的defer和recover:优雅处理错误

Go语言以其简洁、高效和强大的特性受到了开发者的热烈欢迎。在错误处理方面,Go语言提供了一种优雅的机制,即通过defer和recover组合来处理恐慌(panic)错误。本文将详细介绍Go语言中的defer和recover机制,探讨其工作原理…...

4.15 TCP Keepalive 和 HTTP Keep-Alive 是一个东西吗?

目录 HTTP 的 Keep-Alive TCP 的 Keepalive 总结: HTTP的Keep-Alive,是应用层(用户态)实现的,称为HTTP长连接; TCP的Keepalive,是由TCP层(内核态)实现的,…...

如何在VSCode中将html文件打开到浏览器

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

2022年03月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:拦截导弹 某国为了防御敌国的导弹袭击, 发展出一种导弹拦截系统。 但是这种导弹拦截系统有一个缺陷: 虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。 某天, 雷达捕捉到敌国的…...

五公里场地训练笔记(完整版)

由于考研和口罩等原因,停跑了比较长的时间。中长距离就是这样,修为尽失,大概是要从头开始了,不过还是要乐观的面对,CHEER UP! 翻看咕咚软件,以前的PB是21:12,在2017年9月…...

【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

使用 OpenAI GPT 模型的最佳实践

推荐:使用NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 为了帮助用户获得最佳输出,OpenAI 提供了使用 GPT 模型的最佳实践。这来自体验,因为许多用户不断尝试使用此模型并找到了最有效的方法。 在本文中,我将总结使用 Ope…...

解除用户账户控制提醒

解决用户账户控制提醒 1. 前言2. 解决用户账户控制提醒2.1 控制面板2.2 注册表2.3 UAC服务 结束语 1. 前言 当我们使用电脑时,有时进行安装应用或者打开应用时,总会弹出一个提示框,要选择点击是否允许程序运行; 系统经常弹出用户…...

行业追踪,2023-08-23

自动复盘 2023-08-23 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...

算法修炼Day60|● 84.柱状图中最大的矩形

LeetCode:84.柱状图中最大的矩形 84. 柱状图中最大的矩形 - 力扣(LeetCode) 1.思路 双指针思路,以当前数组为中心,借助两个数组存放当前数柱左右两侧小于当前数柱高度的索引,进行h*w的计算。注意首尾节点的左侧索引…...

前端面试题css(一)

题目 盒子垂直水平居中如何实现text-align:center vertical-align: middle水平垂直居中布局positionmargin水平垂直居中布局 grid栅格化布局及其兼容性介绍一下BFC触发 BFC 的条件包括:常见的用途包括: 写过的动画效果overflow有哪些属性visible&#x…...

.NETCORE中关于swagger的分组

有些时候我们的项目接口过多,就希望对应的swagger能够执行分组,网络上的几乎是千篇一律的分组方法,会累死! 这里提供一个更加高效的分组方法,比如你可以说哪些模块分到哪个组,哪些权限分到哪个组&#xff…...

4.1011

目录 四次挥手中收到乱序的FIN包会如何处理? 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么? 四次挥手中收到乱序的FIN包会如何处理? 如果FIN报文比数据包先道道客户端,此时FIN是一个乱序报文,此时…...

uniapp中引入axios的错误?

场景 在unaipp中使用axios npm i axios 下载完成后 然后在页面中使用 axios.get(“http://3000/searchS”) 然后报错 Adapter http’ is not available in the build 原因 在 UniApp 中使用 Axios 发送 HTTP 请求时,如果出现错误 “Adapter http’ is not available…...

Discuz!论坛发帖标题字数限制80字符可以修改吗?修改发帖标题字数的方法

Discuz!论坛发帖标题字数限制80字符修改方法 1.数据库修改2.修改JS验证字符数文件3.修改模板中写死的字符限制数4.修改函数验证文件5.修改语言包文件6.更新缓存 Discuz X3.4论坛网站帖子标题字数限制80字符,当我们想使用长标题的时候就得一删再删,实在是…...

R语言画样本不均衡组的箱线图

# 导入 ggplot2 包 library(ggplot2)# 示例数据框&#xff0c;包含数值数据和分组信息 data <- data.frame(Group c(rep("Group A",10), rep("Group B",15),rep("Group C",20)),Value c(rnorm(10, mean 10, sd 2),rnorm(15, mean 15, sd…...

ArcGIS学习总结(19)——要素转点与空间连接(属性表字段映射)

1.在新创建的面矢量数据的属性表中没有对应的字段信息&#xff0c;为了能够和有属性信息的数据进行匹配&#xff0c;使其具有对应字段的信息。 2.需要匹配的矢量文件属性表信息。 3.对新创建的矢量文件执行要素转点&#xff1a;数据管理工具→要素→要素转点。 4.选择分析工…...

【每日一题Day306】LC228汇总区间 | 双指针

汇总区间【LC228】 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范…...

vue中实现echarts三维散点图

需要安装 echarts 同时引入 echarts-gl 我安装的版本&#xff1a; "echarts": "^5.3.2", "echarts-gl": "^2.0.9", import Vue from "vue"; import * as echarts from "echarts"; Vue.prototype.$echarts echa…...

多头自注意力机制的代码实现

文章目录 1、自注意力机制2、多头注意力机制 transformer的整体结构&#xff1a; 1、自注意力机制 自注意力机制如下&#xff1a; 计算过程&#xff1a; 代码如下&#xff1a; class ScaledDotProductAttention(nn.Module):def __init__(self, embed_dim, key_size, value_…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...