非零基础自学Golang
文章目录
- 非零基础自学Golang
- 第10章 错误处理
- 10.3 Go语言宕机
- 10.4 宕机恢复
- 10.4.1 recover捕获宕机
- 10.4.2 recover应用
第10章 错误处理
10.3 Go语言宕机
一般而言,只有当程序发生不可逆的错误时,才会使用panic方法来触发宕机。
panic方法是Go语言的一个内置函数,使用panic方法后,程序的执行将直接中断。
panic方法的源代码如下,由于其参数为空接口类型,因此我们可以传入任意类型的值作为宕机内容:
func panic(v interface{})
[ 动手写 10.3.1]
package main
import "fmt"
func main() {
panic("Serious bug")
fmt.Println("Invalid code") //程序退出,无法执行该行代码
}
运行结果
调用panic方法后,之后的代码都是无效代码,因为程序会直接退出。
如果遇到以下情形,可以调用panic方法来退出程序:
- 程序处于失控状态且无法恢复,继续执行将会影响其他正常程序,引发操作系统异常甚至是死机。
- 发生不可预知的错误。
10.4 宕机恢复
10.4.1 recover捕获宕机
Go语言通过内置函数recover来捕获宕机,类似于其他编程语言中的try-catch机制。
在使用panic方法触发宕机后,且在退出当前函数前,会调用延迟执行语句defer,代码示例如下:
[ 动手写 10.4.1]
package main
import "fmt"
func protect() {
defer func() {
fmt.Println("func protect exit")
}()
panic("Serious bug") // 触发宕机
}
func main() {
defer func() { // protect 函数退出前执行defer 语句
fmt.Println("func main exit")
}()
protect()
fmt.Println("Invalid code")
}
运行结果
以上程序流程如下:
- protect函数内的panic方法触发宕机。
- 由于protect函数内的匿名函数通过defer语句延迟执行,在panic方法触发宕机后,且在退出protect函数前,会执行protect函数中的匿名函数,打印“func protect exit”。
- 由于main函数内的匿名函数通过defer语句延迟执行,在main函数退出前会执行main函数中的匿名函数,打印“func main exit”。
- 程序退出。
由于defer语句延迟执行的特性,我们可以通过**“defer语句+匿名函数+recover方法”**来完成对宕机的捕获。
[ 动手写 10.4.2]
package main
import "fmt"
func protect() {
defer func() {
if err := recover(); err != nil { //recover() 获取panic() 传入的参数
fmt.Println(err)
}
}()
panic("Serious bug")
}
func main() {
protect()
fmt.Println("valid code")
}
运行结果
以上程序通过recover方法获取到panic()传入的参数,进行打印展示,程序从宕机点退出当前函数后继续执行。
10.4.2 recover应用
在实际编程中,我们会专门封装一个函数,以一种安全模式来运行所有传入的方法,核心思想与动手写10.4.2类似,代码如下:
[ 动手写 10.4.3]
package main
import "fmt"
func protect(f func()) { // 以安全模式来运行所有传入的方法
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
f()
}
func main() {
protect(func() { // 模拟函数1
fmt.Println("This is function 1")
panic("Serious bug from function 1")
})
protect(func() { // 模拟函数2
fmt.Println("This is function 2")
panic("Serious bug function 2")
})
fmt.Println("valid code")
}
运行结果
没毛病,protect函数用于以安全模式运行所有传入的匿名函数或闭包后的执行函数,即使发生panic,主程序仍然能继续正常运行。