一文详细谈谈GoLang的panic和error

目录
  • 前言
  • 1. panic
  • 2. recover
  • 3. error
  • 总结

前言

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

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
}

总结

到此这篇关于GoLang中panic和error的文章就介绍到这了,更多相关GoLang的panic和error内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Golang中panic与recover的区别

    目录 前言 流程 关于recover 前言 与defer类似的是,goroutine 中也有一个_panic链表头指针指向一个_panic链,发生panic的时候也是在链表头插入_panic结构体(执行gopanic) 在执行过程中发生了panic.那么panic以后的代码不会执行,转而执行panic的逻辑,再执行defer,执行到的defer要将started标记为true,同时将其defer结构体中的_panic指针指向当前的_panic,表示这个defer是由该panic触发的.再去执行d

  • Go中recover与panic区别详解

    概念 panic 与 recover 是 Go 的两个内置函数,这两个内置函数用于处理 Go 运行时的错误. panic用于主动抛出错误, recover 用来捕获panic 抛出的错误. func main() { //捕获 异常 defer func() { if p := recover(); p != nil { fmt.Printf("panic recover! p: %v", p) //类型判断 str, ok := p.(string) if ok { err := e

  • Go 自定义error错误的处理方法

    Go的error比较灵活.但是自身对error处理的机制有不太好用,我们可以自定义错误输出: 只要所有实现了Error()方法的对象都可以, 这里给个比较简单的demo,后续整理一个error的优化封装: package main import ( "fmt" ) type NameEmtpyError struct { name string } //NameEmtpyError实现了 Error() 方法的对象都可以 func (e *NameEmtpyError) Error()

  • 浅析golang开发Error的使用详解

    Error是Go语言开发中最基础也是最重要的部分,跟其他语言的try catch的作用基本一致,想想在PHP JAVA开发中,try catch 不会使用,或者使用不灵活,就无法感知到程序运行中出现了什么错误,是特别可怕的一件事. Error 基础 Golang中 error类型就是一个最基本interface,定义了一个Error()的方法 type error interface { Error() string } 平常使用最多的是这样的 errors.New("error")

  • GO语言标准错误处理机制error用法实例

    本文实例讲述了GO语言标准错误处理机制error用法.分享给大家供大家参考.具体分析如下: 在 Golang 中,错误处理机制一般是函数返回时使用的,是对外的接口,而异常处理机制 panic-recover 一般用在函数内部. error 类型介绍 error 类型实际上是抽象了 Error() 方法的 error 接口,Golang 使用该接口进行标准的错误处理. 复制代码 代码如下: type error interface {  Error() string } 一般情况下,如果函数需要返

  • golang panic及处理机制

    目录 一 panic机制 二 实例 2.1 main用recover 2.2 func用recover 2.3 func用recover且开创goroutine 2.4 goroutine中panic 2.5 func1内嵌func2中panic且func2做处理 2.6 func1内嵌func中panic且func1做处理 一 panic机制 panic会将这个异常不断向上抛出,直到有地方处理它,如果有处理,则不会再向上抛出.倘若没有处理,那么最终会导致main挂掉. golang虽然没有tr

  • 详解go中panic源码解读

    panic源码解读 前言 本文是在go version go1.13.15 darwin/amd64上进行的 panic的作用 panic能够改变程序的控制流,调用panic后会立刻停止执行当前函数的剩余代码,并在当前Goroutine中递归执行调用方的defer: recover可以中止panic造成的程序崩溃.它是一个只能在defer中发挥作用的函数,在其他作用域中调用不会发挥作用: 举个栗子 package main import "fmt" func main() { fmt.

  • Golang中panic的异常处理

    目录 前言 如何恢复panic造成的程序崩溃 何时使用panic 前言 Golang中当程序发生致命异常时(比如数组下标越界,注意这里的异常并不是error),Golang程序会panic(运行时恐慌).当程序发生panic时,程序会执行当前栈中的defer 函数列表.然后打印引发panic的具体信息,最后进程退出,本篇文章我们一起探讨Golang中的panic以及如何利用defer 和 recover 来恢复这种致命的异常 分析造成panic堆栈信息 func main() {     f1(

  • Go error的使用方式详解

    目录 概述 error使用方式 1.直接判等 2.组合error接口,构建更强大的error接口 3.Errno模式 4.Go1.13的Wrap模式 5. Go版本低时的链式error 概述 当我们需要在Go项目中设计error,就不得不先知道Go error几种常用方法.标准库是一个非常好的学习方式,除此之外Go1.13的errors特性也需要掌握. error使用方式 1.直接判等 这里的判等又分为变量判等和类型判等.适用于pkg中预先定义好了多个error变量或类型,err只可能是这些变量

  • 一文详细谈谈GoLang的panic和error

    目录 前言 1. panic 2. recover 3. error 总结 前言 首先说一下: 错误指的是可能出现问题的地方出现了问题.如打开件失败,这种情况在意料之中 .异常指的是不应该出现问题的地方出现了问题.如引用了空指针,这种情况在意料之外 Go 提供两种错误处理方式 函数返回 error 类型对象判断错误 panic 异常 1. panic Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界.空指针引用等.这些运行时错误会引起painc异常. 一般而言,当

  • GoLang中panic与recover函数以及defer语句超详细讲解

    目录 一.运行时恐慌panic 二.panic被引发到程序终止经历的过程 三.有意引发一个panic并让panic包含一个值 四.施加应对panic的保护措施从而避免程序崩溃 五.多条defer语句多条defer语句的执行顺序 一.运行时恐慌panic panic是一种在运行时抛出来的异常.比如"index of range". panic的详情: package main import "fmt" func main() { oneC := []int{1, 2,

  • 一文详解Golang中net/http包的实现原理

    目录 前言 http包执行流程 http包源码分析 端口监听 请求解析 路由分配 响应处理 前言 Go语言自带的net/http包提供了HTTP客户端和服务端的实现,实现一个简单的http服务非常容易,其自带了一些列结构和方法来帮助开发者简化HTTP服务开发的相关流程,因此我们不需要依赖任何第三方组件就能构建并启动一个高并发的HTTP服务器,net/http包在编写web应用中有很重要的作用,这篇文章会学习如何用 net/http 自己编写实现一个 HTTP Server 并探究其实现原理,具体

  • 一文详解Golang 定时任务库 gron 设计和原理

    目录 cron 简介 gron 定时参数 源码解析 Cron Entry 按照时间排序 新增定时任务 启动和停止 Schedule 扩展性 经典写法-控制退出 结语 cron 简介 在 Unix-like 操作系统中,有一个大家都很熟悉的 cli 工具,它能够来处理定时任务,周期性任务,这就是: cron. 你只需要简单的语法控制就能实现任意[定时]的语义.用法上可以参考一下这个Crontab Guru Editor,做的非常精巧. 简单说,每一个位都代表了一个时间维度,* 代表全集,所以,上面

  • 一文详解Golang的中间件设计模式

    目录 背景 Demo 验证结论 背景 记录一下自己在go开发和学习上的一些笔记 最近在看一些rpc框架的使用原理和源码的时候,对中间件的实现非常感兴趣,然后也看了一下grpc的中间件的用法,也看了别的框架的中间件的设计,感觉grpc的还算是比较容易弄懂,于是记录一下这个常用中间件的实现的一个原理的demo(吐槽一下其他的rpc框架分为inbound和outbound的middleware感觉好像有点复杂化了,所以我也不知道哪种设计会比较好,楼主是java出身,所以对反射走aop的那种模式比较熟悉

  • 一文详解Golang中consul的基本使用

    目录 consul consul的安装和部署 docker安装 consul镜像的启动 启动一个tcp_health_check的服务注册 http版 服务发现 consul consul是一个开源服务注册和服务发现的中心,可以用于微服务的注册和服务之间的调用的发现,帮助上游服务找到下游服务的具体ip:port或者是domain,也可以使用dns的方式让consul帮你去做转发,具体介绍请看consul的官网,consul区分server-agent和client-agent,client-ag

  • Golang捕获panic堆栈信息的讲解

    golang当中panic的时候如果启动的goroutine比较多,刷的信息满屏都是,在终端工具上因为刷的信息太多,找不到前边的信息,因此很有必要程序自己捕获panic,并且将错误信息输出到文件当中,以便定位排查问题. Golang捕获panic堆栈信息 func PanicTrace(kb int) []byte { s := []byte("/src/runtime/panic.go") e := []byte("\ngoroutine ") line := [

  • 一文搞懂Golang文件操作增删改查功能(基础篇)

    前言 目前,Golang 可以认为是服务器开发语言发展的趋势之一,特别是在流媒体服务器开发中,已经占有一席之地.很多音视频技术服务提供商也大多使用 Golang 语言去做自己的后台服务开发,业内貌似已经达成了某种共识.今天我们不聊特别深奥的机制和内容,就来聊一聊 Golang 对于文件的基本操作. 正文 开始之前,讲一个非常有意思的小桥段.最开始接触 Golang 这种语言的时候,我总感觉它和 Google 单词比较像,所以一度怀疑二者有什么联系.后来一查才发现,二者确实有联系,晕- -因为 G

  • 详细谈谈MYSQL中的COLLATE是什么

    前言 在mysql中执行show create table <tablename>指令,可以看到一张表的建表语句,example如下: CREATE TABLE `table1` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `field1` text COLLATE utf8_unicode_ci NOT NULL COMMENT '字段1', `field2` varchar(128) COLLATE utf8_unicode_ci

随机推荐