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 …...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
