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

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固定频率的同步降压型转换器&#xff0c;因此具有高达90%以上的充电效率&#xff0c;自身发热量极小。包括完整的充电终止电路、自动再充电和一个达1%的4.2V预设充电电压&#xff0c;内部集成了防反灌保护、输…...

PDF校对工具正式上线,为用户提供卓越的文档校对解决方案

为满足当下对数字化文档校对的精准需求&#xff0c;我们今日正式发布全新的PDF校对工具。经过深入的技术研发与细致的测试&#xff0c;该工具旨在为企业和个人用户带来一个高效且准确的PDF文档校对平台。 PDF校对工具的主要特性&#xff1a; 1.全面性校对&#xff1a;工具支持…...

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&#xff08;美国&#xff09; 2、官⽅⽹站 3、登录ChatGPT ![在这里插入图片描述](https://img-blog.csdnimg.cn/26901096553a4ba0a5c88c49b2601e6a.png 填⼊帐号、密码&#xff0c;点击登录。登录成功&#xff0c;如下 3、和ChatGPT对话 开始…...

idea启动正常,打成jar包时,启动报错

背景 自己写了个小程序&#xff0c;在idea中启动正常&#xff0c;达成jar包发布时&#xff0c;启动报错。 Caused by: java.sql.SQLException: unknown jdbc driver : at com.alibaba.druid.util.JdbcUtils.getDriverClassName(JdbcUtils.java:517) at com.alibaba.druid.pool…...

软考高级系统架构设计师系列论文八十九:论软件需求分析方法和工具的选用

软考高级系统架构设计师系列论文八十九:论软件需求分析方法和工具的选用 一、软件需求相关知识点二、摘要三、正文四、总结一、软件需求相关知识点 软考高级系统架构设计师:论软件需求管理...

java八股文面试[JVM]——类加载器

一、类加载器的概念 类加载器是Java虚拟机用于加载类文件的一种机制。在Java中&#xff0c;每个类都由类加载器加载&#xff0c;并在运行时被创建为一个Class对象。类加载器负责从文件系统、网络或其他来源中加载类的字节码&#xff0c;并将其转换为可执行的Java对象。类加载器…...

CSS中如何实现元素之间的间距(Margin)合并效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 外边距合并的示例&#xff1a;⭐ 如何控制外边距合并&#xff1a;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff…...

【实操干货】如何开始用Qt Widgets编程?(三)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 在本文中&#xff0…...

基于深度学习的图像风格迁移发展总结

前言 本文总结深度学习领域的图像风格迁移发展脉络。重点关注随着GAN、CUT、StyleGAN、CLIP、Diffusion Model 这些网络出现以来&#xff0c;图像风格迁移在其上的发展。本文注重这些网络对图像风格迁移任务的影响&#xff0c;以及背后的关键技术和研究&#xff0c;并总结出一…...

小程序页面间有哪些传递数据的方法?

使用全局变量实现数据传递 在 app.js 文件中定义全局变量 globalData&#xff0c; 将需要存储的信息存放在里面使用的时候&#xff0c;直接使用 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意为跨源资源共享&#xff08;Cross origin resource sharing&#xff09;&#xff0c;它是一个W3C标准&#xff0c;由一系列HTTP Header组成&#xff0c;这些 HTTP Header决定了浏览器是否允许JavaScript 代码成功获得跨源请求的服务器响应。 在说CORS之前&#xff0c;先…...

科技资讯|三星再申请智能戒指商标,智能穿戴进入更小型化发展

三星正在积极扩展可穿戴设备生态&#xff0c;近日向英国知识产权局提交了名为“Samsung Curio”的新商标&#xff0c;其分类为“Class 9”&#xff0c;可能会用于未来的智能戒指。 智能戒指&#xff1a; 可穿戴计算机本质上的智能手环、智能项链、智能眼镜和智能戒指&#xff1…...

HarmonyOS开发第一步,熟知开发工具DevEco Studio

俗话说的好&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;走进HarmonyOS第一步&#xff0c;开发工具必须先行&#xff0c;当然了&#xff0c;关于开发工具的使用&#xff0c;官网和其他的博客也有很多的讲解&#xff0c;但是并没有按照常用的功能进行概述&#xff…...

【应急响应】Linux常用基础命令

文章目录 文件和目录操作文件内容查看和编辑系统信息查询权限管理进程管理网络管理 文件和目录操作 ls&#xff1a;列出目录内容&#xff08;例如 ls -l 显示详细信息&#xff09; cd&#xff1a;切换工作目录 pwd&#xff1a;显示当前工作目录 touch&#xff1a;创建空文件&a…...

什么是Pytorch?

当谈及深度学习框架时&#xff0c;PyTorch 是当今备受欢迎的选择之一。作为一个开源的机器学习库&#xff0c;PyTorch 为研究人员和开发者们提供了一个强大的工具来构建、训练以及部署各种深度学习模型。你可能会问&#xff0c;PyTorch 是什么&#xff0c;它有什么特点&#xf…...

Baidu World 2023,定了!

1. 定了&#xff0c;Baidu World 2023 终于定了&#xff0c;今年的 Baidu World 将会于 2023-10-17 日在北京首钢园正式召开&#xff0c;主题为『生成未来 / PROMPT THE WORLD』&#xff0c;这也是近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 …...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...