Go panic, defer, recover 的异常处理
来源:互联网 发布:loveless world知乎 编辑:程序博客网 时间:2024/05/21 00:52
本内容为部分转载 : http://www.cnblogs.com/ghj1976/archive/2013/02/11/2910114.html
- 1.go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。在Go语言中,使用多值返回来返回错误。不要用异常代替错误,更不要用来控制流程。在极个别的情况下,也就是说,遇到真正的异常的情况下(比如除数为0了)。才使用Go中引入的Exception处理:defer, panic, recover。
- 2.注意: 返回错误值与异常属于两种不同场景, 错误值属于普通正常的函数返回值,并不会导致程序中断执行; 而Go异常在不捕捉的情况下, 会导致程序中断执行;
- 3.代码演示:
- 普通函数,错误值返回
package( "fmt" "errors")func test_common_ret()(int, error){ return 1, errors.new("hello error") //普通的 错误值返回, 不会导致程序中断执行, 返回后继续进行下面的打印语句}func main(){ ret, err := test_common_ret() fmt.Println(ret, err) //打印语句}运行结果:1 hello error
* 进行异常抛出, 但不捕捉, 导致程序中断执行
package( "fmt" "errors")func test_panic_ret()(int, error){ err := errors.New("hello error") ret := 34 panic(err) //此处抛出异常, 未进行异常捕捉,直接导致程序中断执行, 不会继续执行接下来的 return语句和打印语句 return ret, err // 普通错误值返回, }func main(){ ret, err := test_panic_ret() fmt.Println(ret, err) //打印语句}运行结果:panic: hello errorgoroutine 1 [running]: //下面的输出为系统出错的堆栈main.test_panic_ret(0xc042068060, 0xc042037f68, 0x0) F:/Go/src/add/addtesttime.go:268 +0x7fmain.main() F:/Go/src/add/addtesttime.go:272 +0x2d
* 抛出异常, 进行捕捉, 程序不会出现异常中断, 会继续执行后面的语句(不过要注意的是,异常捕捉之后,逻辑并不会恢复到panic那个点去,函数还是会在defer之后返回。)
package( "fmt" "errors")func test_recov_panic_ret()(int, error){ defer func(){ //进行异常捕捉 if err := recover(); err != nil{ fmt.Println(err) } }() err := errors.New("hello error") ret := 34 panic(err) //此处抛出异常, 进行异常捕捉, 不会导致程序中断执行 return ret, err //普通错误值返回 }func main(){ ret, err := test_recov_panic_ret() fmt.Println(ret, err) //打印语句}运行结果:hello error0 <nil>
defer
- defer的思想类似于C++中的析构函数,不过Go语言中“析构”的不是对象,而是函数,defer就是用来添加函数结束时执行的语句。注意这里强调的是添加,而不是指定,因为不同于C++中的析构函数是静态的,Go中的defer是动态的。
- 另外值得一提的是,defer可以多次,这样形成一个defer栈,后defer的语句在函数返回时将先被调用。
panic
- panic 是用来表示非常严重的不可恢复的错误的。在Go语言中这是一个内置函数,接收一个interface{}类型的值(也就是任何值了)作为参数。panic的作用就像我们平常接触的异常。不过Go可没有try…catch,所以,panic一般会导致程序挂掉(除非recover)。所以,Go语言中的异常,那真的是异常了。你可以试试,调用panic看看,程序立马挂掉,然后Go运行时会打印出调用栈。
- 但是,关键的一点是,即使函数执行的时候panic了,函数不往下走了,运行时并不是立刻向上传递panic,而是到defer那,等defer的东西都跑完了,panic再向上传递。所以这时候 defer 有点类似 try-catch-finally 中的 finally。
panic就是这么简单。抛出个真正意义上的异常。
defer
- 上面说到,panic的函数并不会立刻返回,而是先defer,再返回。这时候(defer的时候),如果有办法将panic捕获到,并阻止panic传递,那就异常的处理机制就完善了。
- Go语言提供了recover内置函数,前面提到,一旦panic,逻辑就会走到defer那,那我们就在defer那等着,调用recover函数将会捕获到当前的panic(如果有的话),被捕获到的panic就不会向上传递了,于是,世界恢复了和平。你可以干你想干的事情了。
- 不过要注意的是,recover之后,逻辑并不会恢复到panic那个点去,函数还是会在defer之后返回。
func try(fun func(), handle func(e interface{})) { defer func() { if err := recover(); err != nil { handle(err) } }() fun()}func test_try() { try(func() { panic(errors.New("hahah")) }, func(e interface{}) { fmt.Println(e) })}输出结果:hahah
结论:
Go对待异常(准确的说是panic)的态度就是这样,没有全面否定异常的存在,同时极力不鼓励多用异常。
阅读全文
0 0
- Go的异常处理 defer, panic, recover
- Go的异常处理 defer, panic, recover
- Go的异常处理 defer, panic, recover
- Go的异常处理 defer, panic, recover
- Go panic, defer, recover 的异常处理
- Go的异常处理 defer, panic, recover
- Go的异常处理 defer, panic, recover<转载>
- Go的异常处理 defer, panic, recover<转载>
- Go的异常处理 defer, panic, recover<转载>
- Go的异常处理 defer, panic, recover<转载>
- go语言中的defer、panic、recover处理异常
- Go编程基础—defer、panic、recover处理异常
- go语言中的defer、panic、recover处理异常
- Go-defer,panic,recover
- GO defer panic recover
- Go语言学习笔记 --- defer 、panic 、recover
- GO语言异常处理机制panic和recover分析
- GO语言异常处理机制panic和recover分析
- [leetcode] 91. Decode Ways
- Hibernate,Spring管理获取事务里的Session
- echarts3的简单实践(饼图、柱形图、折线图、地图+散点图)
- Hibernate中对象的三种状态及相互转化
- iOS常用的开发工具
- Go panic, defer, recover 的异常处理
- Python——class的基础知识(Python的实例方法,类方法,静态方法之间的区别及调用关系)
- 15 反射与动态执行
- 如何让CListCtrl选中行恒保持其蓝色高亮状态?
- MySQL事务隔离级别
- 16 Macros
- IllegalArgumentException occured : Parameter value [camera]was not matching type [java.lang.Double]
- 二分图的最大匹配(匈牙利算法)
- 17 Creating Languages