🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 宕机 > **panic()** > 调用panic()方法后,之后代码都是无效的 ``` package main import "fmt" func main() { panic("宕机") fmt.Println("宕机后这里不执行") } ``` ``` // 结果: panic: 宕机 goroutine 1 [running]: main.main() d:/桌面/study/Go/1/hello.go:4 +0x27 exit status 2 ``` ### 宕机恢复 > Go语言使用内置函数recover来捕获宕机 ``` package main import "fmt" func pro() { // 匿名函数 defer func() { // pro函数退出前执行defer语句 fmt.Println("func pro exit") }() panic("Serius bug") } func main() { // 匿名函数 defer func() { // pro函数退出前执行defer语句 fmt.Println("func main exit") }() pro() fmt.Println("Invalid code") } ``` ``` // 结果 func pro exit func main exit panic: Serius bug goroutine 1 [running]: main.pro() d:/桌面/study/Go/1/hello.go:11 +0x49 main.main() d:/桌面/study/Go/1/hello.go:20 +0x3f exit status 2 ``` 原理 1,pro()函数内的panic方法实现宕机 2,由于pro()函数内匿名函数通过defer语句延迟执行,在panic触发宕机后,匿名函数会打印"func pro exit" 3,main()函数内匿名函数通过defer语句延迟执行,退出前会打印"func main exit" 4,程序退出 由于defer语句延迟执行的特性,通过“ defer语句+匿名函数+recover方法”来对宕机的捕捉 ``` package main import "fmt" func pro() { // 匿名函数 defer func() { // pro函数退出前执行defer语句 if err := recover(); err != nil { // recover()捕获panic()传入的参数 fmt.Println(err) } }() panic("Serius bug") } func main() { pro() fmt.Println("valid code") } // 结果 Serius bug valid code ``` 原理 通过recover方法获取到panic传入的参数,进行打印程序从当前宕机点退出当前函数后继续执行 ``` package main import "fmt" func pro(f func()) { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() f() } func main() { pro(func() { fmt.Println("This is func1") panic("bug 1") }) pro(func() { fmt.Println("This is func2") panic("bug 2") }) fmt.Println("valid code") } This is func1 bug 1 This is func2 bug 2 valid code ``` ``` 实际编程中,我们会专门封装一个函数,以一种安全模式来运行传入所有方法 pro函数用于安全模式运行所有传入的匿名函数或闭包的执行函数,即使发生panic,主程序也不会挂 ```