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

【Golang】:错误处理

目录

1. panic 异常

2. recover 捕获异常

3. 自定义错误


1. panic 异常

panic 是 Go 程序在 运行时出现严重错误 时触发的异常机制。

常见触发原因:除零错误、数组/切片越界、空指针引用、明确调用 panic()

panic 发生时:

  1. 程序会立即中断正常执行流程;

  2. 先执行当前函数的 defer 语句

  3. 再沿着调用栈向上逐层返回,并依次执行各层函数的 defer

  4. 如果在最顶层(main 函数)仍未被捕获,则程序崩溃并打印错误信息和调用栈。

package mainimport "fmt"func Division(num1 int, num2 int) int {defer fmt.Println("Division defer...") // 会执行return num1 / num2
}func main() {defer fmt.Println("main defer...") // 会执行// panic 异常:除零result := Division(10, 0)fmt.Printf("result = %d\n", result) // 不会执行fmt.Println("other code...")        // 不会执行
}
/*
Division defer...
main defer...
panic: runtime error: integer divide by zerogoroutine 1 [running]:
main.Division(0x10255ed40?, 0x14000096000?)
/Users/mac/Desktop/test_go/main.go:7 +0x88
main.main()
/Users/mac/Desktop/test_go/main.go:13 +0x64进程 已完成,退出代码为 2
*/

2. recover 捕获异常

1. recover 的作用

recover 是 Go 内建函数,用于 捕获 panic,防止程序直接崩溃。

它必须写在 defer 延迟调用的函数里,否则不起作用。

触发 panic 后,recover 会:

  • 返回 panic 的值(通常是 errorstring);

  • 使程序从 panic 中恢复,继续执行后续代码。

2. 使用

recover 一般写在匿名函数的 defer 里,这样,即使发生 panic,程序也不会崩溃。

defer func() {if r := recover(); r != nil {fmt.Println("捕获到 panic:", r)}
}()
package mainimport ("errors""fmt"
)func Division(num1, num2 int) (res int, err error) {defer func() {if r := recover(); r != nil {err = errors.New(fmt.Sprintf("panic: %v", r))}}()return num1 / num2, nil
}func main() {result, err := Division(10, 0)if err != nil {fmt.Printf("division operation error, err = %v\n", err)} else {fmt.Printf("result = %d\n", result)}fmt.Println("main 函数后续代码仍然会执行")
}// division operation error, err = panic: runtime error: integer divide by zero
// main 函数后续代码仍然会执行

3. 自定义错误

  1. 错误 (error):用于描述可预期、可恢复的问题(比如:文件不存在、网络超时)。
  2. 异常 (panic):用于描述不可恢复的严重问题,或需要强制中断的情况。
  3. errors.New:快速创建一个自定义错误值。
  4. panic(errors.New(...)):主动触发异常。
  5. recover:捕获 panic,让程序继续运行。

1. error 接口

Go 中所有错误都实现了内建的 error 接口,这意味着任何类型只要有 Error() string 方法,就可以作为 error 使用。

type error interface { Error() string 
}

2. 创建错误

// 最常见的方式是用 errors.Newimport "errors"err := errors.New("something went wrong")
fmt.Println(err)  // 输出: something went wrong

3. 使用 panic 主动触发异常

除了运行时错误(除零、数组越界等),我们也可以 主动触发 panic,并传入一个 error 类型:

package mainimport ("errors""fmt"
)func CheckAge(age int) {if age < 0 {panic(errors.New("年龄不能是负数"))}fmt.Println("合法年龄:", age)
}func main() {CheckAge(20)CheckAge(-5)             // 会触发 panicfmt.Println("main 后续代码") // 不会执行
}// 合法年龄: 20
// panic: 年龄不能是负数

4. 结合 recover 进行捕获

通常不会让 panic 直接终止程序,而是配合 recover容错处理

package mainimport ("errors""fmt"
)func CheckAge(age int) {defer func() {if r := recover(); r != nil {fmt.Println("捕获到错误", r)}}()if age < 0 {panic(errors.New("年龄不能是负数"))}fmt.Println("合法年龄:", age)
}func main() {CheckAge(20)CheckAge(-5)             // 会触发 panicfmt.Println("main 后续代码") // 不会执行
}
/*
合法年龄: 20
捕获到错误 年龄不能是负数
main 后续代码
*/

    http://www.xdnf.cn/news/18234.html

    相关文章:

  • AI Search进化论:从RAG到DeepSearch的智能体演变全过程
  • 第12章《学以致用》—PowerShell 自学闭环与实战笔记
  • 第七十七章:多模态推理与生成——开启AI“从无到有”的时代!
  • 计算机程序编程软件开发设计之node..js语言开发的基于Vue框架的选课管理系统的设计与实现、基于express框架的在线选课系统的设计与实现
  • Jenkins - CICD 注入环境变量避免明文密码暴露
  • Python中f - 字符串(f-string)
  • Hadoop入门
  • 前端基础知识版本控制系列 - 05( Git 中 HEAD、工作树和索引之间的区别)
  • 图论水题4
  • 写作路上的迷茫与突破
  • java_spring boot 中使用 log4j2 及 自定义layout设置示例
  • NestJS 手动集成TypeORM
  • 关于第一次接触Linux TCP/IP网络相关项目
  • Docker入门:容器化技术的第一堂课
  • python---装饰器
  • 在线编程题目之小试牛刀
  • [每周一更]-(第155期):Go 1.25 发布:新特性、技术思考与 Go vs Rust 竞争格局分析
  • 回溯剪枝的 “减法艺术”:化解超时危机的 “救命稻草”(一)
  • 机器学习算法篇(十三)------词向量转化的算法思想详解与基于词向量转换的文本数据处理的好评差评分类实战(NPL基础实战)
  • 微服务之间的调用需要走网关么?
  • Linux Shell定时检查日期执行Python脚本
  • Python数据类型转换详解:从基础到实践
  • uniappx 安卓端本地打包的一些总结
  • 【typenum】 16 非零标记及改进建议
  • 【Linux系统】动静态库的制作
  • java之 junit4单元测试Mockito的使用
  • Pycharm Debug详解
  • 深度学习之优化器
  • 数据与模型融合波士顿房价回归建模预测
  • 数据结构(排序篇)——七大排序算法奇幻之旅:从扑克牌到百亿数据的魔法整理术