这篇文章主要介绍“Golang异常控制处理程序错误流程是什么”,在日常操作中,相信很多人在Golang异常控制处理程序错误流程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang异常控制处理程序错误流程是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。在Go语言中,设计者们推荐使用多值返回来返回错误。遇到真正的异常的情况下(比如除数为 0了)。才使用Go中引入的Exception处理:defer, panic, recover。
这几个异常的使用场景可以这么简单描述:Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理
package main import "fmt" func main(){ fmt.Println("c") defer func(){ // 必须要先声明defer,否则不能捕获到panic异常 fmt.Println("d") if err:=recover();err!=nil{ fmt.Println(err) // 这里的err其实就是panic传入的内容,55 } fmt.Println("e") }() f() //开始调用f fmt.Println("f") //这里开始下面代码不会再执行 } func f(){ fmt.Println("a") panic("异常信息") fmt.Println("b") //这里开始下面代码不会再执行 fmt.Println("f") }
输出结果:
c
a
d
异常信息
e
利用recover处理panic指令,recover需要定义在defer匿名函数内
defer需要在panic之前声明,否则当panic时,recover无法捕获到panic
panic无recover情况下,程序会直接崩溃
func TestPanic(t *testing.T) { defer func() { if err := recover(); err != nil { println("recovered") } }() subFun() subFun() } func subFun() { println("subFun") panic("subFun panic") }
输出结果如下,第一个sunFun后面的代码不会执行
subFun
recovered
func subFun(i int) { fmt.Println("subFun,i=", i) panic("subFun panic") } func TestSubGoPanic(t *testing.T) { defer func() { if err := recover(); err != nil { println("recovered2") } }() go subFun(3) subFun(4) println("finish") }
结果
subFun,i= 4
recovered2
subFun,i= 3
--- PASS: TestSubGoPanic (0.00s)
panic: subFun panicgoroutine 21 [running]:
zh.com/base/err.subFun(0x0?)
/Users/albert/file/code/go/zh/gotest/base/err/panic_test.go:34 +0x89
created by zh.com/base/err.TestSubGoPanic
/Users/albert/file/code/go/zh/gotest/base/err/panic_test.go:43 +0x46
recover会执行,但是程序崩溃了
如果 panic 和 recover 发生在同一个协程,那么 recover 是可以捕获的,如果 panic 和 recover 发生在不同的协程,那么 recover 是不可以捕获的
也就是哪个协程有panic,哪个协程里必须要有recover,否则会把整个程序弄崩溃
在使用 Golang 进行开发时,遇到 panic 是非常常见的情况。但是,panic 对于性能的影响是相对较小的,尤其是在实际使用中。
首先,Golang 在运行时会维护一个 panic 堆,用于存储栈中的 panic 对象。当程序遇到 panic 时,会将该 panic 对象添加到 panic 堆中。panic 堆的大小是有限的,如果堆中的对象过多,可能会导致 panic 堆溢出,从而影响程序的性能
func BenchmarkSubFunWithError(b *testing.B) { for i := 0; i < b.N; i++ { go subFunWithError(i) } } func BenchmarkSubFunWithRecover(b *testing.B) { for i := 0; i < b.N; i++ { go subFunWithRecover(i) } } func subFunWithRecover(i int) { //fmt.Println("subFun,i=", i) defer func() { if error := recover(); error != nil { //println("subFunWithRecover_recovered") } }() time.Sleep(time.Second) panic("subFun panic") } func subFunWithError(i int) error { //fmt.Println("subFun,i=", i) time.Sleep(time.Second) return errors.New("subFunWithError") } BenchmarkSubFunWithError-12 673920 1992 ns/op 489 B/op 3 allocs/op BenchmarkSubFunWithRecover-12 1000000 1229 ns/op 240 B/op 2 allocs/op
到此,关于“Golang异常控制处理程序错误流程是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。