Go语言基础-错误处理

news/2024/12/21 20:10:58/文章来源:https://www.cnblogs.com/ffff5/p/18447503

Go 语言错误处理机制

错误类型

Go 的内置错误类型通过 error 接口提供了一种简单而有效的错误处理机制。

error 接口

在 Go 中,error 是一个内置接口,定义如下:

type error interface {Error() string
}

error 接口只有一个方法 Error(),返回一个描述错误的字符串。这使得任何实现了 Error() 方法的类型都可以被视为错误。

创建自定义错误

开发者可以通过实现 error 接口来自定义错误类型。例如:

type MyError struct {Message stringCode    int
}func (e *MyError) Error() string {return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}

在这个例子中,MyError 是一个自定义错误类型,包含错误消息和错误代码。实现 Error() 方法后,MyError 类型可以作为错误使用。

使用内置错误类型

Go 标准库提供了一些内置的错误类型,例如:

fmt.Errorf

用于创建带有格式化字符串的错误。

err := fmt.Errorf("failed to open file: %s", filename)

errors.New

用于创建一个简单的错误。

err := errors.New("an error occurred")

错误包装

从 Go 1.13 开始,可以使用 fmt.Errorf 来包装错误,以便提供更多上下文信息。通过 %w 语法,可以将原始错误作为新错误的一部分:

originalErr := errors.New("original error")
wrappedErr := fmt.Errorf("an additional context: %w", originalErr)

检查错误类型

可以使用 errors.Iserrors.As 来检查错误的类型,方便处理不同类型的错误:

if errors.Is(err, specificErr) {// 处理特定类型的错误
}

返回错误

返回错误的基本用法如下:

func doSomething() error {// 发生错误时返回return fmt.Errorf("an error occurred")
}

检查错误

检查返回错误的基本示例:

if err := doSomething(); err != nil {fmt.Println("Error:", err)
}

panic 与 recover

panic() 是 Go 语言中的一个内置函数,用于触发恐慌状态。它主要用于处理程序中不可恢复的错误,导致程序停止执行并开始回溯。

panic() 被调用时,Go 会执行以下步骤:

  1. 停止当前函数的执行:当前函数会立即停止执行,所有未完成的操作(如 defer 语句)会被执行。
  2. 逐层回溯:程序会逐层回溯,执行每层调用栈中的 defer 语句,直到找到一个可以捕获 panicrecover()
  3. 程序崩溃:如果没有任何 recover() 捕获这个 panic,程序将打印错误信息并退出。

recover() 是 Go 语言中用于处理恐慌状态的内置函数。它的主要作用是捕获因 panic 触发的异常,以便程序能够继续执行,而不是完全崩溃。

recover() 只能在 defer 声明的函数中使用。它的功能是捕获 panic 产生的值,返回该值,如果没有发生 panic,则返回 nil

示例

package mainimport ("fmt"
)func mayPanic() {panic("something went wrong!")
}func safeFunction() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()mayPanic() // 触发 panicfmt.Println("This will not be printed")
}func main() {safeFunction()fmt.Println("Program continues after recovery.")
}

输出结果:

Recovered from panic: something went wrong!
Program continues after recovery.

在上面的示例中,mayPanic 函数触发了一个 panic,但通过 recover() 捕获并处理了这个 panic,程序得以继续执行。

设计模式:返回错误 vs使用 panic

  • 返回错误:这种模式适合于可以预期的错误,如文件未找到、网络请求失败等。调用者可以通过检查错误值来决定下一步的处理逻辑。

    func readFile(filename string) error {// 模拟读取文件错误return fmt.Errorf("file not found: %s", filename)
    }
    
  • 使用 panic:适合处理严重的程序错误,例如逻辑错误、配置错误等。这类错误通常表明代码中存在缺陷,无法继续执行。

    func main() {if err := performCriticalOperation(); err != nil {panic(err) // 不可恢复的错误}
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/808119.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPS股票价格查询EXCEL表格

第一步在表格内使用公式=GetStockSource(Stock_code)查询股票的即时交易信息,Stock_code表示股票代码;第二步通过公式从Source中提取所需要的数据,可以提取股票名称、价格、涨跌幅、收盘价格、成交额、成交量、换手率等。 公式如下: GetStockSource(Stock_code),查询股票即…

【2024.10.4 闲话】0/99+

当符卡收取100次后,收率显示会从xx/99+变为master,收率master是成为神触第一步呢(笑)。今日推歌:没有。明天可能有。 今日 set:也没有。话说应该没人知道 set 是什么吧,总之不是 std::set。[ARC176E] Max Vector 给你两个长度为 \(N\) 的正整数序列: \(X=(X_1,X_2,\dot…

2024 ciscn WP

一、MISC1.火锅链观光打卡打开后连接自己的钱包,然后点击开始游戏,答题八次后点击获取NFT,得到有flag的图片没什么多说的,知识问答题兑换 NFTFlag{y0u_ar3_hotpot_K1ng}2.Power Trajectory Diagram方法1:使用py中的numpy和pandas库读取npz文件并保存为csv文件,代码如下:…

30. 协程

1.协程的概念 1.1 定义 进程是操作系统内部运行的程序 线程是进程内部运行的程序 协程是线程内部运行的程序 协程是单线程下的并发,又成微线程,英文名coroutine 1.2 协程的优点协程切换的开销更小 GIL锁导致同一时刻只能运行一个线程,一个线程内不会限制协程数,单线程就可以…

.net core 安装服务

https://www.jianshu.com/p/e1b3b61f876a使用NSSM 后面的代码演示以Asp.net Core 2.1作为演示,其他.Net Core方式一致。 1、确保.Net Core程序可以正常运行 先把Asp.net Core发布,然后直接运行dotnet命令,确保程序可以运行并访问 2、使用NSSM安装dotnet 下载NSSM,使用命…

vs2015安装包丢失或损坏解决工具 或者不能启动

打开“本地组策略编辑器”(gpedit.msc)。展开“计算机配置”>“管理模板”>“系统”>“Internet 通信管理”,然后选择“Internet 通信设置”。选择“关闭自动根证书更新”>,“禁用”,然后选择“确定”或“应用”。  下载最新的组件版本(备份的) https://lea…

uboot 启动自编写程序的方式

uboot 启动自编写程序的方式 uboot 存在 boot 命令。 自己最初在尝试撰写串口程序时,选择了使用汇编来完成。 在这段时间,自己使用 go 命令来尝试载入程序 先是在 Ubuntu 上搭建 tftp 目录 # /etc/default/tftpd-hpaTFTP_USERNAME="tftp" TFTP_DIRECTORY="/ho…

10.Java集合框架_List接口

集合与数组的区别数组:长度开始时必须指定,而且一旦指定,不能修改。 保存的必须为同一类型的元素。 使用数组进行增加/删除元素比较麻烦。集合:可以动态保存任意多个对象,使用比较方便。 提供了一系列方便操作对象的方法: add、remove、set、get。 使用集合添加,删除新元…

20240924

[牛半仙的妹子 Tree(tree)](http://ac.robo-maker.cn/d/contest/p/ZY1044?tid=66f28cd11bca2159e88c8fb0) 我们会发现其实牛半仙发癫时就等于将以前的标记清空,从头开始,所以我们可以考虑根号分治,如果两个牛半仙发癫的时间间隔小于 \(\sqrt n\) ,那么我们可以直接暴力枚举两…

『模拟赛』冲刺CSP联训模拟2

『模拟赛记录』冲刺CSP联训模拟2Rank 不重要了A. 挤压 你说的对,期望怎么能算签呢? 一个重要的性质:一个数的平方可以在二进制下表示为 \(\sum_{i,j}\ s_i\ s_j\ 2^{i+j}\),所以就可以分别求每一位对答案的贡献了。 设 \(f_{i,1/0,1/0}\) 表示到第 \(i\) 个数我们枚举的两位…