Go语言 异常panic和恢复recover用法

背景:Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个异常。在Go语言中,使用多值返回来返回错误。不要用异常代替错误,更不要用来控制流程。在极个别的情况下,才使用Go中引入的Exception处理:defer, panic, recover。

panic:

1、内建函数
2、假如函数F中书写了panic语句,会终止其后要执行的代码,在panic所在函数F内如果存在要执行的defer函数列表,按照defer的逆序执行
比如panic函数内有:
defer   函数1
defer   函数2
defer   函数3
那么执行顺序就是:
函数3
函数2
函数1
3、返回函数F的调用者G,在G中,调用函数F语句之后的代码不会执行,假如函数G中存在要执行的defer函数列表,按照defer的逆序执行,这里的defer 有点类似 try-catch-finally 中的 finally
4、直到goroutine整个退出,并报告错误
 

recover:

1、内建函数
2、用来控制一个goroutine的panicking行为,捕获panic,从而影响应用的行为
3、一般的调用建议
a). 在defer函数中,通过recever来终止一个gojroutine的panicking过程,从而恢复正常代码的执行
b). 可以获取通过panic传递的error
简单来讲:go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。
示例代码  main函数相当于调用者G,f函数相当于函数F
func main() {
fmt.Println("c")
defer func() { // 必须要先声明defer,否则不能捕获到panic异常
fmt.Println("d")
if err := recover(); err != nil {
fmt.Println(err) // 这里的err其实就是panic传入的内容
}
fmt.Println("e")
}()
f() //开始调用f
fmt.Println("f") //这里开始下面代码不会再执行
} func f() {
fmt.Println("a")
panic("异常信息")
fmt.Println("b") //这里开始下面代码不会再执行
}
-------output-------
c
a
d
异常信息
e

  

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

Go语言 异常panic和恢复recover用法的更多相关文章

  1. [日常] Go语言圣经-Panic异常,Recover捕获异常习题

    Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的pan ...

  2. Go语言中异常处理painc()和recover()的用法

    Go语言中异常处理painc()和recover()的用法 1.Painc用法是:用于抛出错误.Recover()用法是:将Recover()写在defer中,并且在可能发生panic的地方之前,先调 ...

  3. Golang 入门系列(十四)defer, panic和recover用法

    以前讲过golang 的基本语法.但是,只是讲了一些基础的语法,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863 ...

  4. 用Go语言异常机制模拟TryCatch异常捕捉

    有的同学看到Go和TryCatch一起出现,心里可能会说,难道Go语言升级了,加入了try...catch语句.哈哈,其实Go语言从创建之初就没打算加入try...catch语句,因为创建Go的那帮大 ...

  5. 用Go语言异常机制模拟TryCatch异常捕捉1

    有的同学看到Go和TryCatch一起出现,心里可能会说,难道Go语言升级了,加入了try...catch语句.哈哈,其实Go语言从创建之初就没打算加入try...catch语句,因为创建Go的那帮大 ...

  6. 《OOC》笔记(3)——C语言变长参数va_list的用法

    <OOC>笔记(3)——C语言变长参数va_list的用法 C语言中赫赫有名的printf函数,能够接受的参数数目不固定,这就是变长参数.C#里也有params这个关键字用来实现变长参数. ...

  7. Atitti 跨语言异常的转换抛出 java js

    Atitti 跨语言异常的转换抛出 java js 异常的转换,直接反序列化为json对象e对象即可.. Js.没有完整的e机制,可以参考java的实现一个stack层次机制的e对象即可.. 抛出Ru ...

  8. C语言中关于scanf函数的用法

    scanf()函数的控制串 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化 ...

  9. C语言对文件的操作函数用法详解2

    fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const  ...

随机推荐

  1. 执行系统命令,subprocess使用说明

    os.system('ls -l') #只执行命令,不能将结果赋予变量 os.system('mkdir test')  #创建test目录 files = os.popen('ls -l').rea ...

  2. In-app Billing 概述

    这个文档讲解了In-app Billing的基础构成和功能,为了能够把In-app Billing功能添加到你的程序中,你需要很好的理解这些内容. 注意: 保证你的应用遵从发布地国家的相关法律. 举例 ...

  3. Python简介及编码

    首先Python是一种语言,因此根据其实现的不同,有Cpython, Jython, IronPython, Pypy等. Python执行流程 $ python /home/hello.py     ...

  4. css动画 文字闪烁效果

    /*定义页面基础CSS*/ body{ font-family: 'microsoft yahei',Arial,sans-serif; color: #EFEFEF; background: #22 ...

  5. 沉淀,再出发:docker的原理浅析

    沉淀,再出发:docker的原理浅析 一.前言 在我们使用docker的时候,很多情况下我们对于一些概念的理解是停留在名称和用法的地步,如果更进一步理解了docker的本质,我们的技术一定会有质的进步 ...

  6. August 28th 2017 Week 35th Monday

    The truth may hurt for a little while but a lie hurts forever. 真相会让我们痛一阵,但谎言会让我们痛一生. Once you make a ...

  7. MVC与EF结合:Contoso大学

    中文教程 1.通过 MVC 5 使用 Entity Framework 6 Code First 入门 https://docs.microsoft.com/zh-cn/aspnet/mvc/over ...

  8. python接口测试-项目实践(八) 完成的接口类和执行脚本

    脱敏后脚本 projectapi.py: 项目接口类 # -*- coding:utf-8 -*- """ xx项目接口类 2018-11 dinghanhua &quo ...

  9. manbook pro和inode联网

    macbook pro可以通过usb以太网转换器来实现有线联网. 1.下载inode 7 2.在终端中输入:sudo /library/StartupItems/iNodeAuthService/iN ...

  10. LVS.md

    LVS 概述 简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由章文嵩博士发起的自由软件项目,官方站点.现在LVS已经是 Linux标准内核的一部分, ...