GO语言中的Defer与Error异常报错详细教程
目录标题
- 一、Defer
- 1. Example
- 2. Deferred methods 延迟方法
- 3. Arguments evaluation 延迟参数
- 4. Stack of defers 延迟程序堆栈
- 5. Practical use of defer 实际使用
- 二、Error
- 1. Example
- 2. PathError
- 3. DNSError
- 4. Direct Comparison 直接比较
- 5. Do not ignore errors 不要忽略错误
- 三、Custom Errors
- 1. Creating custom errors using the New function 创建自定义错误
- 2. Adding more information to the error using Errorf 添加更多信息
- 3. Providing more information about the error using struct type and fields 使用结构类型与字段展示错误
- 4. Providing more information about the error using methods on struct types 使用结构类型与方法展示错误
一、Defer
在Go语言中,defer 关键字用于延迟(defer)函数或方法的执行,即在函数执行完毕后再执行被延迟的代码块。defer 语句通常用于资源释放、
清理操作或确保某些代码在函数执行的最后一刻被执行。下面是对 defer 的几个关键点进行解释:
1.延迟执行: 使用 defer 可以将函数或方法的执行推迟到包含它的函数返回之前。当函数中的 defer 语句被执行时,相应的函数调用被推迟,并被压入一个栈中,直到包含函数返回时才会按照后进先出(LIFO)的顺序执行这些被推迟的函数调用。2.资源释放: defer 经常用于释放资源,比如打开的文件、数据库连接或网络连接等。通过在打开资源后使用 defer 来确保在函数返回之前关闭资源,可以避免资源泄漏,即使函数中途发生错误或提前返回,资源也会被正确释放。3.清理操作:defer 还可以用于执行一些清理操作,例如解锁互斥锁、关闭通道或恢复(recover)错误处理等。通过在函数开始时使用 defer,可以确保在函数执行结束时进行必要的清理。4.顺序执行: 多个 defer 语句按照它们的出现顺序进行执行。第一个 defer 语句的函数调用会在最后一个 defer 语句之前执行,即最后一个被推迟的函数调用会最先执行。
1. Example
package mainimport "fmt"func finished() {fmt.Println("Finished finding largest")}func largest(nums []int) {defer finished() // 延迟执行fmt.Println("Started finding largest")max := nums[0]for _, v := range nums {if v > max {max = v}}fmt.Println("Largest number in", nums, "is", max)}func main() {nums := []int{78, 111, 222, 333}largest(nums)}// Started finding largest// Largest number in [78 111 222 333] is 333// Finished finding largest
2. Deferred methods 延迟方法
type Person struct {firstName stringlastName string}func (p Person) fullName() {fmt.Printf("%s %s", p.firstName, p.lastName)}func main() {p := Person{firstName: "Mei",lastName: "Jin",}defer p.fullName()fmt.Printf("Welcome ")}// Welcome Mei Jin
3. Arguments evaluation 延迟参数
func printA(a int) {fmt.Println("Value of a in deferred function", a)}func main() {a := 5defer printA(a)a = 10fmt.Println("Values of before deferred function call", a)}// Values of before deferred function call 10// Value of a in deferred function 5
4. Stack of defers 延迟程序堆栈
func main() {name := "Like"fmt.Printf("Original String: %s\n", string(name))fmt.Printf("Reversed String: ")for _, v := range name {defer fmt.Printf("%c", v) // defer表示延迟调用 但是堆栈的数据时后进先出 所以导致字符串反转}}// Original String: Like// Reversed String: ekiL
5. Practical use of defer 实际使用
package mainimport ( "fmt""sync")type rect struct { length intwidth int}func (r rect) area(wg *sync.WaitGroup) { defer wg.Done()if r.length < 0 {fmt.Printf("rect %v's length should be greater than zero\n", r)return}if r.width < 0 {fmt.Printf("rect %v's width should be greater than zero\n", r)return}area := r.length * r.widthfmt.Printf("rect %v's area %d\n", r, area)}func main() { var wg sync.WaitGroupr1 := rect{-67, 89}r2 := rect{5, -67}r3 := rect{8, 9}rects := []rect{r1, r2, r3}for _, v := range rects {wg.Add(1)go v.area(&wg)}wg.Wait()fmt.Println("All go routines finished executing")}// rect {8 9}'s area 72 // rect {-67 89}'s length should be greater than zero // rect {5 -67}'s width should be greater than zero // All go routines finished executing
二、Error
1. Example
package mainimport ("fmt""os")func main() {f, err := os.Open("/test.txt") // 没有该文件if err != nil {fmt.Println(err)return}fmt.Println(f.Name(), "Opened successfully")}// open test.txt: The system cannot find the file specified.
2. PathError
package mainimport ("errors""fmt""os")func main() {f, err := os.Open("/test.txt")if err != nil {var pErr *os.PathErrorif errors.As(err, &pErr) {fmt.Println("Failed to open file at path", pErr.Path)return}fmt.Println("Generic error", err)return}fmt.Println(f.Name(), "Opened successfully")}// Failed to open file at path /test.txt
3. DNSError
package mainimport ("errors""fmt""net")func main() {addr, err := net.LookupHost("www.baidu.com")//addr, err := net.LookupHost("golangbot123.com")if err != nil {var dnsErr *net.DNSErrorif errors.As(err, &dnsErr) {if dnsErr.Timeout() { // 超时错误fmt.Println("operation time out")return}if dnsErr.Temporary() { // 临时错误fmt.Println("Temporary error")return}fmt.Println("Generic DNS error", err) // 没有这个站点return}fmt.Println("Generic error", err)return}fmt.Println(addr) // [180.101.50.242 180.101.50.188]}// 没有站点报错 Generic DNS error lookup golangbot123.com: no such host// 有站点 [180.101.50.242 180.101.50.188]
4. Direct Comparison 直接比较
package mainimport ("errors""fmt""path/filepath")func main() {files, err := filepath.Glob("go.mod")if err != nil {if errors.Is(err, filepath.ErrBadPattern) {fmt.Println("Bad pattern error:", err) // syntax error in patternreturn}fmt.Println("Generic error:", err) // 类型错误return}fmt.Println("matched files", files) // 正确打印列表 matched files [go.mod]}
5. Do not ignore errors 不要忽略错误
package mainimport ( "fmt""path/filepath")func main() { files, _ := filepath.Glob("[") // 匹配错误 如果不展示则找起错误就麻烦了fmt.Println("matched files", files)}// matched files []
三、Custom Errors
1. Creating custom errors using the New function 创建自定义错误
package mainimport ("errors""fmt""math")func circleArea(radius float64) (float64, error) {if radius < 0 { // 如果小于0则运行以下return 0, errors.New("Area calculation failed, radius is less than zero")}return math.Pi * radius * radius, nil}func main() {radius := -10.00area, err := circleArea(radius)if err != nil { // 如果为空fmt.Println(err)return}fmt.Printf("Area of circle %0.2f", area)}// Area calculation failed, radius is less than zero
2. Adding more information to the error using Errorf 添加更多信息
package mainimport ("fmt""math")func circleArea(radius float64) (float64, error) {if radius < 0 { // 如果小于0则运行以下return 0, fmt.Errorf("Area calculation failed, radius %0.2f is less than zero", radius)}return math.Pi * radius * radius, nil}func main() {radius := -10.00area, err := circleArea(radius)if err != nil { // 如果为空fmt.Println(err)return}fmt.Printf("Area of circle %0.2f", area)}// Area calculation failed, radius -10.00 is less than zero
3. Providing more information about the error using struct type and fields 使用结构类型与字段展示错误
package mainimport ("errors""fmt""math")type areaError struct {err stringradius float64}func (e *areaError) Error() string {return fmt.Sprintf("radius %0.2f:%s", e.radius, e.err)}func circleArea(radius float64) (float64, error) {if radius < 0 { // 如果小于0则运行以下return 0, &areaError{err: "radius is negative",radius: radius,}}return math.Pi * radius * radius, nil}func main() {radius := -20.0area, err := circleArea(radius)if err != nil {var areaError *areaErrorif errors.As(err, &areaError) {fmt.Printf("Area calculation failed, radius %0.2f is less than zero", areaError.radius)return}fmt.Println(err)return}fmt.Printf("Area of rectangle %0.2f", area)}// Area calculation failed, radius -20.00 is less than zero
4. Providing more information about the error using methods on struct types 使用结构类型与方法展示错误
package mainimport ( "errors""fmt")type areaError struct { err string //error descriptionlength float64 //length which caused the errorwidth float64 //width which caused the error}func (e *areaError) Error() string { return e.err}func (e *areaError) lengthNegative() bool { return e.length < 0}func (e *areaError) widthNegative() bool { return e.width < 0}func rectArea(length, width float64) (float64, error) { err := ""if length < 0 {err += "length is less than zero"}if width < 0 {if err == "" {err = "width is less than zero"} else {err += ", width is less than zero"}}if err != "" {return 0, &areaError{err: err,length: length,width: width,}}return length * width, nil}func main() { length, width := -5.0, -9.0area, err := rectArea(length, width)if err != nil {var areaError *areaErrorif errors.As(err, &areaError) {if areaError.lengthNegative() {fmt.Printf("error: length %0.2f is less than zero\n", areaError.length)}if areaError.widthNegative() {fmt.Printf("error: width %0.2f is less than zero\n", areaError.width)}return}fmt.Println(err)return}fmt.Println("area of rect", area)}// error: length -5.00 is less than zero// error: width -9.00 is less than zero
技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!
相关文章:
GO语言中的Defer与Error异常报错详细教程
目录标题 一、Defer1. Example2. Deferred methods 延迟方法3. Arguments evaluation 延迟参数4. Stack of defers 延迟程序堆栈5. Practical use of defer 实际使用 二、Error1. Example2. PathError3. DNSError4. Direct Comparison 直接比较5. Do not ignore errors 不要忽略…...
AP6315 DC单节锂电池充电IC 同步2A锂电芯片
概述 是一款面向5V交流适配器的2A锂离子电池充电器。它是采用1.5MHz固定频率的同步降压型转换器,因此具有高达90%以上的充电效率,自身发热量极小。包括完整的充电终止电路、自动再充电和一个达1%的4.2V预设充电电压,内部集成了防反灌保护、输…...
PDF校对工具正式上线,为用户提供卓越的文档校对解决方案
为满足当下对数字化文档校对的精准需求,我们今日正式发布全新的PDF校对工具。经过深入的技术研发与细致的测试,该工具旨在为企业和个人用户带来一个高效且准确的PDF文档校对平台。 PDF校对工具的主要特性: 1.全面性校对:工具支持…...
WSL 配置 Oracle 19c 客户端
Windows WSL 登陆后显示如下: Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 4.4.0-19041-Microsoft x86_64)* Documentation: https://help.ubuntu.com* Management: https://landscape.canonical.com* Support: https://ubuntu.com/advantageSystem information as…...
ChatGPT⼊门到精通(1):ChatGPT 是什么
⼀、直观感受 1、公司 OpenAI(美国) 2、官⽅⽹站 3、登录ChatGPT  at com.alibaba.druid.pool…...
软考高级系统架构设计师系列论文八十九:论软件需求分析方法和工具的选用
软考高级系统架构设计师系列论文八十九:论软件需求分析方法和工具的选用 一、软件需求相关知识点二、摘要三、正文四、总结一、软件需求相关知识点 软考高级系统架构设计师:论软件需求管理...
java八股文面试[JVM]——类加载器
一、类加载器的概念 类加载器是Java虚拟机用于加载类文件的一种机制。在Java中,每个类都由类加载器加载,并在运行时被创建为一个Class对象。类加载器负责从文件系统、网络或其他来源中加载类的字节码,并将其转换为可执行的Java对象。类加载器…...
CSS中如何实现元素之间的间距(Margin)合并效果?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 外边距合并的示例:⭐ 如何控制外边距合并:⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅ÿ…...
【实操干货】如何开始用Qt Widgets编程?(三)
Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 在本文中࿰…...
基于深度学习的图像风格迁移发展总结
前言 本文总结深度学习领域的图像风格迁移发展脉络。重点关注随着GAN、CUT、StyleGAN、CLIP、Diffusion Model 这些网络出现以来,图像风格迁移在其上的发展。本文注重这些网络对图像风格迁移任务的影响,以及背后的关键技术和研究,并总结出一…...
小程序页面间有哪些传递数据的方法?
使用全局变量实现数据传递 在 app.js 文件中定义全局变量 globalData, 将需要存储的信息存放在里面使用的时候,直接使用 getApp() 拿到存储的信息 App({// 全局变量globalData: {userInfo: null} }) 使用 wx.navigateTo 与 wx.redirectTo 的时候&…...
bh002- Blazor hybrid / Maui 保存设置快速教程
1. 建立工程 bh002_ORM 源码 2. 添加 nuget 包 <PackageReference Include"BootstrapBlazor.WebAPI" Version"7.*" /> <PackageReference Include"FreeSql" Version"*" /> <PackageReference Include"FreeSql.…...
同源政策与CORS
CORS意为跨源资源共享(Cross origin resource sharing),它是一个W3C标准,由一系列HTTP Header组成,这些 HTTP Header决定了浏览器是否允许JavaScript 代码成功获得跨源请求的服务器响应。 在说CORS之前,先…...
科技资讯|三星再申请智能戒指商标,智能穿戴进入更小型化发展
三星正在积极扩展可穿戴设备生态,近日向英国知识产权局提交了名为“Samsung Curio”的新商标,其分类为“Class 9”,可能会用于未来的智能戒指。 智能戒指: 可穿戴计算机本质上的智能手环、智能项链、智能眼镜和智能戒指࿱…...
HarmonyOS开发第一步,熟知开发工具DevEco Studio
俗话说的好,工欲善其事,必先利其器,走进HarmonyOS第一步,开发工具必须先行,当然了,关于开发工具的使用,官网和其他的博客也有很多的讲解,但是并没有按照常用的功能进行概述ÿ…...
【应急响应】Linux常用基础命令
文章目录 文件和目录操作文件内容查看和编辑系统信息查询权限管理进程管理网络管理 文件和目录操作 ls:列出目录内容(例如 ls -l 显示详细信息) cd:切换工作目录 pwd:显示当前工作目录 touch:创建空文件&a…...
什么是Pytorch?
当谈及深度学习框架时,PyTorch 是当今备受欢迎的选择之一。作为一个开源的机器学习库,PyTorch 为研究人员和开发者们提供了一个强大的工具来构建、训练以及部署各种深度学习模型。你可能会问,PyTorch 是什么,它有什么特点…...
Baidu World 2023,定了!
1. 定了,Baidu World 2023 终于定了,今年的 Baidu World 将会于 2023-10-17 日在北京首钢园正式召开,主题为『生成未来 / PROMPT THE WORLD』,这也是近4年来 Baidu World 再次恢复线下举行。 有些小伙伴们如果还不知道什么是 Baid…...
ProxySQL+MGR高可用搭建
服务器点位 NODEIPmgr_node0192.165.26.200mgr_node1192.165.25.201mgr_node2192.165.26.202proxysql192.165.26.199 修改主机名 # 登录192.165.26.200 hostnamectl set-hostname mgr_node0 # 登录192.165.26.201 hostnamectl set-hostname mgr_node1 # 登录192.165.26.202 …...
Wan2.2-I2V-A14B与数据库联动:自动化生成电商商品动态详情页视频
Wan2.2-I2V-A14B与数据库联动:自动化生成电商商品动态详情页视频 1. 电商视频制作的痛点与机遇 电商平台每天都有大量新品上架,传统的商品详情页视频制作方式面临巨大挑战。一个中型电商平台每月可能新增上千款商品,如果每款商品都需要人工…...
EVA-01保姆级教程:Qwen2.5-VL-7B多模态大模型在EVA-01中的本地化安全部署
EVA-01保姆级教程:Qwen2.5-VL-7B多模态大模型在EVA-01中的本地化安全部署 1. 引言:欢迎来到NERV指挥中心 想象一下,你面前有一个能看懂图片、理解图表、甚至能和你讨论图片里发生了什么的智能助手。现在,我们把这个助手装进了一…...
Ubuntu服务器中文乱码终极解决方案:从locale配置到阿里云重启避坑指南
Ubuntu服务器中文乱码终极解决方案:从locale配置到阿里云重启避坑指南 当你第一次在Ubuntu服务器上看到中文字符变成一堆问号或方框时,那种困惑和挫败感我深有体会。特别是在云服务器环境下,问题往往比本地环境更复杂——即使按照常规教程操作…...
[具身智能-125]:RQT(Robot Qt),一个可以全方位监控ROS2系统内部节点工作状态的可视化超级终端!!!
如果说 RViz2 是机器人的“眼睛”(看 3D 世界),那么 RQT 就是机器人的“听诊器”和“控制台”。它基于 Qt 框架开发,采用插件化架构,让你能在一个窗口里完成对 ROS2 系统内部状态的全方位监控与调试。为了让你更好地利…...
别再只会docker push了!Harbor镜像上传的5个隐藏技巧与实战避坑指南
Harbor镜像上传实战:5个高阶技巧与避坑指南 当你在凌晨三点被CI/CD流水线的失败通知惊醒,发现又是镜像上传问题导致整个发布流程卡住时,就会明白掌握Harbor的进阶用法有多重要。作为企业级容器镜像仓库,Harbor远比简单的docker pu…...
告别黑盒调试:为VS2022和Halcon HImage定制一个带暗色主题的视觉化调试器
为VS2022和Halcon HImage打造沉浸式暗色调试器:从UI优化到高效开发实践 在计算机视觉开发领域,Halcon凭借其强大的图像处理能力成为工业检测、医疗影像等场景的首选工具。然而,长时间面对传统调试界面容易导致视觉疲劳,影响开发效…...
开源工具wxappUnpacker:微信小程序逆向解析实战指南
开源工具wxappUnpacker:微信小程序逆向解析实战指南 【免费下载链接】wxappUnpacker 项目地址: https://gitcode.com/gh_mirrors/wxappu/wxappUnpacker 模块一:工具定位与价值——小程序开发的逆向工程利器 完成本节学习后你将能够:…...
AI 模型推理框架性能分析与对比
AI模型推理框架性能分析与对比 随着人工智能技术的快速发展,AI模型推理框架成为支撑各类应用落地的核心工具。无论是计算机视觉、自然语言处理还是推荐系统,高效的推理框架直接影响模型的响应速度、资源占用和部署成本。本文将从多个维度对比主流AI推理…...
制造业生产管理应用搭建指南:轻流无代码平台完整实施流程——生产效率提升 300% 方法论
制造业生产管理应用搭建指南:轻流无代码平台完整实施流程——生产效率提升 300% 方法论制造业生产管理应用搭建指南:轻流无代码平台完整实施流程——生产效率提升 300% 方法论引言:背景与重要性工信部《智能制造发展规划》明确提出࿰…...
【国家级等保2.0合规必读】:Python扩展模块安全开发规范(含12项强制检查项+自动化检测脚本)
第一章:Python扩展模块安全开发概述Python 扩展模块(C/C 编写的 .so/.dll 文件)是提升性能、复用底层库或与系统交互的关键手段,但其直接操作内存、绕过 Python 运行时保护机制的特性,也使其成为安全风险的高发区。开发…...
