为什么80%的码农都做不了架构师?>>>   

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

这几个异常的使用场景可以这么简单描述:Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。

例子代码:

package main

import "fmt"

func main(){

defer func(){ // 必须要先声明defer,否则不能捕获到panic异常

fmt.Println("c")

if err:=recover();err!=nil{

fmt.Println(err) // 这里的err其实就是panic传入的内容,55

}

fmt.Println("d")

}()

f()

}

func f(){

fmt.Println("a")

panic(55)

fmt.Println("b")

fmt.Println("f")

}

输出结果:

a

c

55

d

exit code 0, process exited normally.

参考: http://blog.csdn.net/ghost911_slb/article/details/7831574

defer

defer 英文原意: vi. 推迟;延期;服从   vt. 使推迟;使延期。

defer的思想类似于C++中的析构函数,不过Go语言中“析构”的不是对象,而是函数,defer就是用来添加函数结束时执行的语句。注意这里强调的是添加,而不是指定,因为不同于C++中的析构函数是静态的,Go中的defer是动态的。

func f() (result int) {

deferfunc()

{

result++

}()

return0

}

上面函数返回1,因为defer中添加了一个函数,在函数返回前改变了命名返回值的值。是不是很好用呢。但是,要注意的是,如果我们的defer语句没有执行,那么defer的函数就不会添加,如果把上面的程序改成这样:

func f() (result int) {

return0

deferfunc()

{

result++

}()

return0

}

上面的函数就返回0了,因为还没来得及添加defer的东西,函数就返回了。

另外值得一提的是,defer可以多次,这样形成一个defer栈,后defer的语句在函数返回时将先被调用。

参考: http://weager.sinaapp.com/?p=31

panic

panic 英文原意:n. 恐慌,惊慌;大恐慌  adj. 恐慌的;没有理由的  vt. 使恐慌  vi. 十分惊慌

panic 是用来表示非常严重的不可恢复的错误的。在Go语言中这是一个内置函数,接收一个interface{}类型的值(也就是任何值了)作为参数。panic的作用就像我们平常接触的异常。不过Go可没有try…catch,所以,panic一般会导致程序挂掉(除非recover)。所以,Go语言中的异常,那真的是异常了。你可以试试,调用panic看看,程序立马挂掉,然后Go运行时会打印出调用栈。

但是,关键的一点是,即使函数执行的时候panic了,函数不往下走了,运行时并不是立刻向上传递panic,而是到defer那,等defer的东西都跑完了,panic再向上传递。所以这时候 defer 有点类似 try-catch-finally 中的 finally。

panic就是这么简单。抛出个真正意义上的异常。

recover

recover 英文原意: vt. 恢复;弥补;重新获得   vi. 恢复;胜诉;重新得球   n. 还原至预备姿势

上面说到,panic的函数并不会立刻返回,而是先defer,再返回。这时候(defer的时候),如果有办法将panic捕获到,并阻止panic传递,那就异常的处理机制就完善了。

Go语言提供了recover内置函数,前面提到,一旦panic,逻辑就会走到defer那,那我们就在defer那等着,调用recover函数将会捕获到当前的panic(如果有的话),被捕获到的panic就不会向上传递了,于是,世界恢复了和平。你可以干你想干的事情了。

不过要注意的是,recover之后,逻辑并不会恢复到panic那个点去,函数还是会在defer之后返回。

用Go实现类似 try catch 的异常处理有个例子在:

[plain] view plaincopy

package main

//实现 try catch 例子

func Try(fun func(), handler func(interface{})) {

defer func() {

if err := recover(); err != nil {

handler(err)

}

}()

fun()

}

func main() {

Try(func() {

panic("foo")

}, func(e interface{}) {

print(e)

})

}

结论:

Go对待异常(准确的说是panic)的态度就是这样,没有全面否定异常的存在,同时极力不鼓励多用异常。

转载于:https://my.oschina.net/qibin/blog/323337

golang学习的点点滴滴:异常处理 defer, panic, recover相关推荐

  1. Go的异常处理 defer, panic, recover

    Go的异常处理 defer, panic, recover 参考文章: (1)Go的异常处理 defer, panic, recover (2)https://www.cnblogs.com/ghj1 ...

  2. go defer,panic,recover详解 go 的异常处理

    golang中defer,panic,recover是很常用的三个特性,三者一起使用可以充当其他语言中try-catch-的角色,而defer本身又像其他语言的析构函数 defer defer后边会接 ...

  3. Go案例说明defer panic recover

    defer推迟  recover恢复  panic恐慌 通过一个案例解释:发送邮件的 发送不成功要修改数据表的邮件发送状态值 发送邮件的内部sendEmail出现错误  要去修改数据表的状态值了 发送 ...

  4. golang panic recover return defer的逻辑顺序问题

    package mainimport "fmt"//验证golang return defer recover 之间的顺序关系func main() {defer func() { ...

  5. recover 没有捕获异常_GO语言异常处理机制panic和recover分析

    本文实例分析了GO语言异常处理机制panic和recover.分享给大家供大家参考.具体如下: Golang 有2个内置的函数 panic() 和 recover(),用以报告和捕获运行时发生的程序错 ...

  6. go panic recover 异常处理

    go panic recover 异常处理 参考文章: (1)go panic recover 异常处理 (2)https://www.cnblogs.com/zhishuai/p/8043064.h ...

  7. DataWhale Golang(十、异常处理)

    DataWhale & Golang(十.异常处理) 学习大纲: 目录 DataWhale & Golang(十.异常处理) 学习大纲 10.异常处理 10.1 error 注意 10 ...

  8. go 异常捕获和处理(panic/recover)

    异常处理 Golang 没有结构化异常,使用 panic 抛出错误,recover 捕获错误. 异常的使用场景简单描述:Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个 ...

  9. golang学习笔记(基础篇)

    LCY~~Golang学习笔记 一.Go语言开发环境 ##安装Go开发包以及VsCode Go开发包与vscode配置安装教程网址:https://www.liwenzhou.com/posts/Go ...

  10. 118云原生编程语言Golang学习笔记

    Golang学习笔记 文章目录 1.Go简介 1.1 简介 1.2 设计初衷 1.3 Golang vs Java 1.4 应用领域 1.5 用go语言的公司 2.Go下载和安装 2.1 开发工具 2 ...

最新文章

  1. logistic回归 如何_第七章:利用Python实现Logistic回归分类模型
  2. c语言使用数组计算最大数。_程序设计入门——C语言_浙江大学_第10次开课
  3. java不同项目加token访问_实战:你用SpringBoot集成JWT来实现一下token验证,可否?...
  4. 《电子基础与维修工具核心教程》——2.4 电阻的串并联
  5. DELPHI GetClassName - 获取指定窗口的类名
  6. 实验一 MATLAB软件的使用
  7. Linux系统的Shell编程
  8. 2016技术众包风云:挑战与机遇并行!
  9. QProcess实现进程通信
  10. 汇总一下那几个常用定理 高斯定理 泊松方程 亚阈值电流 跨导
  11. 快速插入参考文献的方法
  12. 文字加下划线单选按钮效果,RadioGroup实现
  13. C++和java的区别和联系
  14. Linux 版本查询常用命令
  15. 阿里系App抓包分析(三)
  16. 用python将图片变为油画_Python也能成为毕加索?我用Python给小姐姐画了幅油画
  17. 重力感应G-Sensor 方向介绍
  18. 笔记本通过无线网络访问台式机服务器
  19. php微信群发接口,微信公众平台群发接口问题
  20. Orc-Battle

热门文章

  1. paip.myeclipse7 java webservice 最佳实践o228
  2. paip.c++程序崩溃的汇编级别调试-打印堆栈-gcc gdb
  3. paip.解决Invalid byte 2 of 2-byte UTF-8 sequence.
  4. HDF5: 读写速度与文件的大小
  5. 2018美国基金业年鉴-数据图表简版
  6. 大数据 对冲基金Cayman Atlantic
  7. 阿里云王伟民:数据库的策略与思考
  8. 第六届开源操作系统年度技术会议将在12月16日杭州浙江大学举办
  9. 【优化调度】基于matlab改进的遗传算法求解风电场优化调度问题【含Matlab源码 1245期】
  10. 【裂缝识别】基于matlab GUI BP神经网络路面裂缝识别系统【含Matlab源码 1063期】