一文详细谈谈GoLang的panic和error

作者:渣渣帅 时间:2024-05-13 10:45:15 

前言

首先说一下: 错误指的是可能出现问题的地方出现了问题。如打开件失败,这种情况在意料之中 。异常指的是不应该出现问题的地方出现了问题。如引用了空指针,这种情况在意料之外

Go 提供两种错误处理方式

  • 函数返回 error 类型对象判断错误

  • panic 异常

1. panic

Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等。这些运行时错误会引起painc异常。

一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(可以先理解成线程)中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。panic value通常是某种错误信息。对于每个goroutine,日志信息中都会有与之相对的,发生panic时的函数调用堆栈跟踪信息。通常,我们不需要再次运行程序去定位问题,日志信息已经提供了足够的诊断依据。因此,在我们填写问题报告时,一般会将panic异常和日志信息一并记录。不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常;panic函数接受任何值作为参数。当某些不应该发生的场景发生时,我们就应该调用panic。虽然Go的panic机制类似于其他语言的异常,但panic的适用场景有一些不同。由于panic会引起程序的崩溃,因此panic一般用于严重错误,如程序内部的逻辑不一致。

panic可以手工调用,但是 Go 官方建议尽量不要使用panic,每一个异常都应该用 error 对象捕获。如果异常出现了,但没有被捕获并恢复,Go 程序的执行就会被终止,即便出现异常的位置不在主 Goroutine 中也会这样。

总结来说:

panic是一个严重错误机制,它会导致程序终止,并依次逆序执行 panic 所在函数可能存在的 defer 函数列表,然后返回该函数的调用方。recover 内置函数可用于捕获 panic,重新恢复程序正常执行流程,但是 recover 函数只有在 defer 内部使用才有效

此外,当 panic() 触发的宕机发生时, panic() 后面的代码将不会被运行,但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用

2. recover

1. recover 是一个 Go 语言的内建函数,可以让进入宕机流程中的 goroutine 恢复过来。

2. 用来控制一个goroutine的panicking行为,捕获panic,从而影响应用的行为

3. 一般的调用建议

a). 在defer函数中,通过recever来终止一个gojroutine的panicking过程,从而恢复正常代码的执行

b). 可以获取通过panic传递的error

简单来讲:go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。

4. 在正常的执行过程中,调用 recover 会返回 nil 并且没有其他任何效果;

注意:利用recover处理panic指令,defer必须在panic之前声明,否则当panic时,recover无法捕获到panic.

总结来说 Go 语言没有异常系统,其使用 panic 触发宕机类似于其他语言的抛出异常, recover 的宕机恢复机制就对应其它语言中的 try/catch 机制。

panic 和 recover 的关系

panic 和 recover 的组合有如下特性:

有 panic 没 recover ,程序宕机。

有 panic 也有 recover ,程序不会宕机,执行完对应的 defer 后,从宕机点退出当前函数后继续执行。

注意:在 panic 触发的 defer 函数内,可以继续调用 panic ,进一步将错误外抛,直到程序整体崩溃。如果想在捕获错误时设置当前函数的返回值,可以对返回值使用命名返回值方式直接进行设置。

示例:

package main

func test() {
defer func() {
if err := recover(); err != nil { // recover 捕获错误。
println(err.(string)) // 将 interface{} 转型为具体类型。
}
}()
panic("panic error!")// panic 抛出错误
}
func main() {
test()
}

3. error

go中的错误处理,是通过返回值的形式来出来,要么你忽略,要么你处理(处理也可以是继续返回给调用者),对于golang这种设计方式,我们会在代码中写大量的if判断,以便做出决定。

对于err如果是nil就代表没有错误,如果不是nil就代表程序出问题了,需要对错误进行处理了。

示例:

func main() {
conent,err:=ioutil.ReadFile("filepath")
if err !=nil{
//错误处理
}else {
fmt.Println(string(conent))
}
}

此外,error类型是go语言的一种内置类型,使用的时候不用特定去import,他本质上是一个接口,

type error interface{
 Error() string //Error()是每一个订制的error对象需要填充的错误消息,可以理解成是一个字段Error
}

来源:https://blog.csdn.net/qq_39458487/article/details/124798684

标签:golang,panic,error
0
投稿

猜你喜欢

  • vue中el-table两个表尾合计行联动同步滚动条实例代码

    2023-07-02 17:08:56
  • python进程类subprocess的一些操作方法例子

    2021-08-26 16:21:35
  • JS中FormData类实现文件上传

    2024-04-10 10:50:10
  • mysql中影响数据库性能的因素讲解

    2024-01-28 02:34:46
  • 使用numpy实现矩阵的翻转(flip)与旋转

    2023-01-31 01:03:18
  • python中尾递归用法实例详解

    2023-10-09 06:46:15
  • 实例讲解PHP验证邮箱是否合格

    2023-11-22 07:05:53
  • C#中的委托和事件

    2007-09-26 20:50:00
  • 基于vue-ssr的静态网站生成器VuePress 初体验

    2024-05-09 09:32:38
  • Python Selenium自动化获取页面信息的方法

    2023-08-22 18:29:31
  • 一文解决django 2.2与mysql兼容性问题

    2024-01-28 03:26:01
  • 在Python的web框架中编写创建日志的程序的教程

    2021-11-25 05:14:07
  • Go channel实现原理分析

    2024-05-05 09:30:29
  • numpy排序与集合运算用法示例

    2022-08-25 10:23:06
  • Go语言开发中redis的使用详解

    2024-02-14 12:58:27
  • python3利用tcp实现文件夹远程传输

    2023-09-03 07:44:38
  • Python调用服务接口的实例

    2021-06-04 18:22:06
  • 浅谈订单重构之 MySQL 分库分表实战篇

    2024-01-13 00:53:36
  • Python数据可视化之matplotlib.pyplot绘图的基本参数详解

    2022-06-10 12:19:48
  • python爬虫教程之bs4解析和xpath解析详解

    2023-09-22 19:43:06
  • asp之家 网络编程 m.aspxhome.com