Golang 中的 panic 与 recover 理解
2017-05-07 17:28
639 查看
Golang 有2个内置的函数 panic() 和 recover(),用以报告和捕获运行时发生的程序错误,与 error 不同,panic-recover 一般用在函数内部。一定要注意不要滥用 panic-recover,可能会导致性能问题。
使用panic抛出异常,抛出异常后将立即停止当前函数的执行并运行所有被defer的函数,然后将panic抛向上一层,直至程序carsh。但是也可以使用被defer的recover函数来捕获异常阻止程序的崩溃,recover只有被defer后才是有意义的。
必须注意:
1. defer 需要放在 panic 之前定义,另外recover只有在 defer 调用的函数中才有效。
2. recover处理异常后,逻辑并不会恢复到 panic 那个点去,函数跑到 defer 之后的那个点.
3. 多个 defer 会形成 defer 栈,后定义的 defer 语句会被最先调用
panic (主动爆出异常) 与 recover (收集异常)
recover 用来对panic的异常进行捕获. panic 用于向上传递异常,执行顺序是在 defer 之后。
下面举个含有异常的例子:
如果不把这个异常panic recover处理的化,那么就会发生下面的情况.
下面是处理panic的例子.
那么上面代码的运行结果是:
上面go代码实例中,异常是我们通过panic方法主动抛出来的,但如果真的就出现了未知的异常咋办?
我们可以看到出现的异常会走到defer这一步,defer这里可以打印具体的异常信息,defer运行完之后不能回到原点,控制权会被扔到该函数的外层,也就是调用这个函数的层,对应上面的代码也就是main()函数。
上面go代码运行结果是:
使用panic抛出异常,抛出异常后将立即停止当前函数的执行并运行所有被defer的函数,然后将panic抛向上一层,直至程序carsh。但是也可以使用被defer的recover函数来捕获异常阻止程序的崩溃,recover只有被defer后才是有意义的。
必须注意:
1. defer 需要放在 panic 之前定义,另外recover只有在 defer 调用的函数中才有效。
2. recover处理异常后,逻辑并不会恢复到 panic 那个点去,函数跑到 defer 之后的那个点.
3. 多个 defer 会形成 defer 栈,后定义的 defer 语句会被最先调用
panic (主动爆出异常) 与 recover (收集异常)
recover 用来对panic的异常进行捕获. panic 用于向上传递异常,执行顺序是在 defer 之后。
下面举个含有异常的例子:
func f() { for { fmt.Println("1") a := []string{"a","b"} fmt.Println(a[3]) // 这里slice越界异常了 /*panic("bug")*/ fmt.Println("4") time.Sleep(1 * time.Second) } }
如果不把这个异常panic recover处理的化,那么就会发生下面的情况.
1 panic: runtime error: index out of range goroutine 1 [running]: panic(0xda9c0, 0x8201c8090) /usr/local/go/src/runtime/panic.go:464 +0x3e6 main.f() /Users/dxy/gg.go:23 +0x33b main.main() /Users/dxy/gg.go:16 +0x14 exit status 2
下面是处理panic的例子.
import ( "fmt" "time" ) func main() { defer func() { //必须要先声明defer,否则不能捕获到panic异常 fmt.Println("2") if err := recover(); err != nil { fmt.Println(err) //这里的err其实就是panic传入的内容,bug } fmt.Println("3") }() f() } func f() { for { fmt.Println("1") panic("bug") fmt.Println("4") //不会运行的. time.Sleep(1 * time.Second) } }
那么上面代码的运行结果是:
1 2 bug 3
上面go代码实例中,异常是我们通过panic方法主动抛出来的,但如果真的就出现了未知的异常咋办?
package main import ( "fmt" "time" ) func main() { f() fmt.Println("end") } func f() { defer func() { //必须要先声明defer,否则不能捕获到panic异常 fmt.Println("netdxy.cn start") if err := recover(); err != nil { fmt.Println(err) //这里的err其实就是panic传入的内容,"bug" } fmt.Println("netdxy.cn end") }() for { fmt.Println("1") a := []string{"a", "b"} fmt.Println(a[3]) // 越界访问,肯定出现异常 panic("bug”) // 上面已经出现异常了,所以肯定走不到这里了。 fmt.Println("4") //不会运行的. time.Sleep(1 * time.Second) } }
我们可以看到出现的异常会走到defer这一步,defer这里可以打印具体的异常信息,defer运行完之后不能回到原点,控制权会被扔到该函数的外层,也就是调用这个函数的层,对应上面的代码也就是main()函数。
上面go代码运行结果是:
1 netdxy.cn start runtime error: index out of range netdxy.cn end end
相关文章推荐
- 【GoLang】panic defer recover 深入理解
- GO_05_2:Golang 中 panic、recover、defer 的用法
- golang recover from panic situation: - reflect: call of reflect.Value.Elem on struct Value
- golang中recover和panic用法
- GOLANG的PANIC和RECOVER
- Golang异常处理-panic与recover
- golang panic and recover
- golang之defer、panic、recover
- golang用panic和recover做业务流程中断的尝试
- Golang从入门到精通(二十一):Golang错误处理之panic-recover
- 理解Defer、Panic和Recover
- 理解Defer、Panic和Recover
- golang中的defer panic recover
- golang recover panic 流程控制的可达与不可达
- Golang panic recover
- Golang中的defer, panic, recover
- golang 函数-defer-recover-panic
- Golang中的panic和recover
- golang panic recover
- golang学习的点点滴滴:异常处理 defer, panic, recover