panic
panic,让当前的程序进入恐慌,中断程序的执行。panic()是一个内建函数,可以中断原有的控制流程
package main
import "fmt"
func TestA() {
fmt.Println("func TestA()")
}
func TestB() {
panic("func TestB():panic")
}
func TestC() {
fmt.Println("func TestC()")
}
func main() {
TestA()
TestB()
TestC()
}
通常情况下,向程序使用方报告错误状态的方式可以时返回一个额外的error类型值。但是,当遇到不可恢复的错误状态时,如数组访问越界、空指针引用等,这些运行时错误会引起panic异常。这时,上述错误的处理方式显然就不合适了。
需要注意的是,不应通过调用panic()函数来报告普通的错误,而应该只把它作为报告致命错误的一种方式。当某种不应该发生的场景发生时调用panic()
package main
import "fmt"
func TestA() {
fmt.Println("func TestA()")
}
func TestB(x int) {
var a [100]int
a[x] = 1000
}
func TestC() {
fmt.Println("func TestC()")
}
func main() {
TestA()
TestB(101)
TestC()
}
recover
panic异常一旦被引发就会导致程序崩溃,Go语言为开发者提供了专用于"拦截"运行时painc的内建函数recover().
recover()可以让进入恐慌流程的Goroutine恢复过来并重新获得流程控制权,需要注意的是,recover()让程序恢复,必须在延迟函数中执行。就是说,recover()仅在延迟函数中有效
在正常的程序运行过程中,调用recover()会返回nil,并且没有其他任何效果。如果当前的Goroutine陷入恐慌,调用recover()可以捕获panic()的输入值,是程序恢复正常运行。
package main
import (
"fmt"
)
func main() {
funcA()
funcB()
funcC()
fmt.Println("main over")
}
func funcA() {
fmt.Println("这是funcA")
}
func funcB() {
defer func() {
if msg := recover(); msg != nil {
fmt.Println("恢复了!获取recover的返回值:", msg)
}
}()
fmt.Println("这是funcB")
for i := 0; i < 10; i++ {
fmt.Println("i:", i)
if i == 5 {
panic("funcB恐慌了")
}
}
}
func funcC() {
defer func() {
fmt.Println("执行延迟函数")
msg := recover()
fmt.Println("获取recover的返回值:", msg)
}()
fmt.Println("这是funcC")
panic("funcC恐慌了")
}