一起重温Golang中的异常处理啊?

  • 1.Golang语言中没有其他语言中的try...catch...语句来捕获异常和异常恢复
  • 2.在Golang中我们通常会使用panic关键字来抛出异常,在defer中使用recover来捕获异常进行具体逻辑处理
  • 3.Golang中我们通常会在函数或方法中返回error结构对象来判断是否有异常出现

注意事项

  • 1.利用recoverpanic指令,defer必须放在panic之前定义(panic会终止其后要执行的代码).
  • 2.recover只有在defer调用的函数中才有效,否则recover无法捕获到panic.
  • 3.recover处理异常后,业务逻辑会跑到defer之后的处理片段中
  • 4.多个defer会形成defer栈
  • 5.panic会等到整个goroutine退出才会报告错误

常规使用

  1. panic以及recover参数类型为空接口(可存储任何类型对象)interface{}
/*
func panic(v interface{})
func recover() interface{}
执行顺序:panic()->带recover的defer
输出结果:
oh my god!panic.
解释:
defer中的recover成功捕获到了panic的异常
*/package main
import ("fmt"
)
func main() {defer func() {if err := recover(); err != nil {fmt.Println(err)}}()panic("oh my god!panic.")
}
  1. 延迟调用中引发的错误,可被后续延迟调用捕获(仅最后一个错误被捕获)
/*
执行顺序:panic()->带panic的defer匿名函数->带recover()的defer匿名函数
输出结果:
catch the panic
解释:
defer中的recover仅能捕获最后一个错误
package main
import ("fmt"
)
func main() {defer func() {if err := recover();err != nil {fmt.Println("catch the panic")}}()defer func() {panic("oh my god! panic.")}()panic("something panic!")}
  1. 捕获函数recover()只有在defer调用内直接调用才会终止,否则返回nil
/*
代码执行顺序:panic->在匿名函数中嵌套recover的defer函数->带fmt的defer->带recover的defer->在匿名函数中调用recover的defer
输出结果:
defer inner
<nil>
defer recover panic error
解释: 多个defer之间形成defer栈,最底部的defer优先执行;第三个defer打印了recover()的零值`nil`,仅有第一个defer成功捕获了最底部的panic("panic error")
*/
package main
import "fmt"
func main() {defer func() {fmt.Println("defer recover",recover())}()defer recover()defer fmt.Println(recover())defer func() {func(){fmt.Println("defer inner")recover()}()}()panic("panic error")
}
  1. 将代码块放置在匿名函数中可实现在函数逻辑中进行异常恢复,而不影响主函数
/*
代码执行顺序:匿名函数中的panic语句->匿名函数中i自加运算->匿名函数中的fmt->匿名函数中的defer->主函数中的fmt
输出结果:
i is: 2
解释:panic会终止其之后的执行,因此优先执行匿名函数中的panic之后便被defer中的recover捕获,将i赋值为2,其后匿名函数退出开始继续执行主函数中的fmt.Println语句
*/
package main
import "fmt"
func main() {test()
}
func test() {var i intfunc() {defer func(){if err := recover();err != nil {i = 2}}()panic("something panic!")i  = 8fmt.Println("no panic, i is:",i)}()fmt.Println("i is:",i)
}
  1. goroutine中的recover

注意:如果一个没有recovergoroutine发生了panic,那么整个进程都会挂掉

/*
sync.WaitGroup用来等待一组goroutine的结束,Add方法用来设置等待的goroutine数量,Done方法表示一个goroutine运行结束,使用Wait方法将全部的goroutine阻塞住,直到全部goroutine执行完毕代码执行顺序:goroutine中的逻辑->wg.Wait()->fmt.Println
输出结果:
panic recover assignment to entry in nil map
donw
解释:
在goroutine中我们声明了一个info的map[string]string类型,我们都知道在map,slice,channel都是引用类型,需要使用make函数进行初始化操作之后进行赋值。而这里直接使用info["name"] = "BGBiao"进行赋值导致panic,fmt.Println函数就会被终止执行,从而执行带recover的defer,之后执行带wg.Done()的defer并退出goroutine执行主程序逻辑
*/
package main
import ("fmt""sync"
)
func main() {var wg sync.WaitGroupwg.Add(4)go func() {defer wg.Done()defer func() {if err := recover();err != nil {fmt.Println("panic recover",err)}}()var info map[string]stringinfo["name"] = "BGBiao"fmt.Println(info)}()wg.Wait()fmt.Println("done")
}

欢迎关注我的公众号: BGBiao,一起进步~

再读Golang中的异常处理相关推荐

  1. golang中container/list包中的坑

    转载地址:golang中container/list包中的坑 - Go语言中文网 - Golang中文社区 golang中list包用法可以参看golang中container/list包用法_che ...

  2. golang中并发sync和channel

    golang中并发sync和channel chenbaoke · 2014-12-08 13:00:01 · 19151 次点击 · 预计阅读时间 5 分钟 · 不到1分钟之前 开始浏览 这是一个创 ...

  3. php协程和goroutine,golang中四种方式实现子goroutine与主协程的同步

    如何实现子goroutine与主线程的同步 第一种方式:time.sleep(),这种方式很太死板,就不演示了. 第二种方式:使用channel机制,每个goroutine传一个channel进去然后 ...

  4. golang中http协议实现

    golang中http协议实现 写了一个爬虫,发现出现了socket泄露的情况.百度了一下发现是缺少了Response.Body.Close(),所以导致连接 没有被正常的关闭.也没有被gc回收.下面 ...

  5. 记一次golang中sync.Map并发创建、读取的问题

    记一次golang中sync.Map并发创建.读取的问题  cunfate https://www.jianshu.com/p/f472e79909bc 背景: 我们有一个用go做的项目,其中用到了z ...

  6. golang中json.Number妙用

    golang中json.Number妙用 最近跟某斯调试一个API接口,接口返回数据是json格式 ,按文档描述是一个整型数据,于是定义如下 type Data struct {Api int `js ...

  7. Java笔记整理六(File类,递归,字节流IO,字符流IO,流中的异常处理,属性集Properties,缓冲流,转换流,序列化,打印流)

    1.File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 文件和目录路径名的抽象表示 java把文件和文件夹封装位为一个File类,我们可 ...

  8. golang 中 channel 的详细使用、使用注意事项及死锁分析

    什么是 channel 管道 它是一个数据管道,可以往里面写数据,从里面读数据. channel 是 goroutine 之间数据通信桥梁,而且是线程安全的. channel 遵循先进先出原则. 写入 ...

  9. golang中的atomic,以及CAS操作

    CAS无锁算法 要实现无锁(lock-free)的非阻塞算法有多种实现方法,其中CAS(比较与交换,Compare and swap)是一种有名的无锁算法.CAS是CPU指令,在大多数处理器架构,包括 ...

最新文章

  1. 中如何构造有参和无惨_CAD制图初学入门:CAD机械软件中如何构造孔?
  2. 线程中应该注意的问题
  3. springboot 自动配置
  4. distinct和group by不能一起用_内裤用热水洗更好吗?能不能和袜子一起洗?了解后炎症或能少困扰...
  5. LOJ-10096(强连通+bfs)
  6. 轻松Ghost XP系统!
  7. app和外部应用的关联及应用举例
  8. 毕业的那天,程序员师兄竟然让我去做这一行
  9. mysqldump全量恢复_mysql全量备份和快速恢复的方法整理
  10. Python datatime date
  11. multisim安装后无法连接数据库_Kepserver连接Mysql教程(一)MySQL5.5数据库安装
  12. (Trie树)leetcode208: Implement Trie,79:Word Search,DFS与BFS(python实现),212:Word Search2...
  13. 诺基亚java软件下载_诺基亚手机安装JAVA软件程序
  14. eclipse 语言包在线更新地址
  15. 【Python游戏】Python各大游戏合集:超级玛丽、天天酷跑、我的世界、魔塔、雷霆战机 | 附带源码
  16. excel工作簿合并怎么处理?
  17. [leetcode]剑指offer(C++版题解)
  18. CANFiber是什么?
  19. 客户关系管理项目——客户管理模块设计
  20. 测度论--长度是怎样炼成的[zz]

热门文章

  1. 用python字符画生日快乐_用字符组成的图案:”生日快乐等
  2. 学习数据库开发的建议和忠告
  3. 智慧应急安全管控平台
  4. libevent - select NFDBITS fd_mask 计算
  5. 2.1剖析一个Jsp页面
  6. 最强开源考试系统-卷王
  7. [机缘参悟-44]:鬼谷子-第八摩篇- 摩者,顺而抚之也, 摩得其情,则顺而抚之,以成其事.
  8. WPF去除边框的方法
  9. 自己动手实现一次性图片验证码
  10. PPT作品分享——新能源汽车市场战火纷飞,群雄逐鹿,谁主沉浮 — 双积分解读