🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## Panic 和 Recover 本节将向你介绍上一章中首先提到的技巧。该技术涉及`panic()`和`recover()`函数的使用,将在`panicRecover.go`中进行介绍,同样分为三部分。 第一段代码: ```Go package main import ( "fmt" ) func a() { fmt.Println("Inside a()") defer func() { if c := recover(); c != nil { fmt.Println("Recover inside a()!") } }() fmt.Println("About to call b()") b() fmt.Println("b() exited!") fmt.Println("Exiting a()") } ``` 除了`import`,此部分还包括`a()`函数的实现。函数`a()`的最重要部分是延迟代码块,该代码块实现了一个匿名函数,当调用`panic()`时将调用该匿名函数。 第二段代码: ```Go func b() { fmt.Println("Inside b()") panic("Panic in b()!") fmt.Println("Exiting b()") } ``` 最后一段代码: ```Go func main() { a() fmt.Println("main() ended!") } ``` 执行`panicRecover.go`产生如下输出: ```shell $ go run panicRecover.go Inside a() About to call b() Inside b() Recover inside a()! main() ended! ``` 这个输出结果让人有点惊讶。因为,从输出中可以看到,`a()`函数没有正常结束,它的最后两个语句没有得到执行: ```Go fmt.Println("b() exited!") fmt.Println("Exiting a()") ``` 不过,好在`panicRecover.go`程序会按我们的意愿结束而不会发生崩溃,因为在`defer`中使用的匿名函数控制了异常情况。还要注意,函数`b()`对函数`a()`一无所知;但是,函数 `a()`包含处理函数`b()`异常情况的 Go 代码。