go语言学习笔记 — 基础 — 高级数据类型 — 函数(12):防止程序崩溃—— 宕机恢复(recover)

无论是代码运行错误由Runtime层抛出的panic崩溃(如空指针访问,除数为0等情况),还是主动触发的panic崩溃,都可以使用defer和recover实现错误捕捉和恢复,使代码在崩溃后继续运行。

go语言没有异常系统,使用panic触发宕机类似其他语言的抛出异常,那么recover宕机恢复机制就对应try/catch捕获异常机制。


1. 让程序在崩溃时继续执行

下面代码实现函数保护作用,该函数传入一个匿名函数,当传入函数以任何形式发生panic崩溃时,可以把崩溃错误打印出来,同时允许代码继续执行,不会使整个进程崩溃。

package func_test

import (
	"fmt"
	"runtime"
	"testing"
)

// 声明描述错误的结构体,成员是保存错误的执行函数
type panicContext struct {
	function string
}

// 创建一个保护函数ProtectRun
func ProtectRun(entry func()) {
	defer func() { // 延迟处理函数
		err := recover() // 发生宕机时,recover()获取panic传入的上下文并打印。defer延迟调用闭包

		switch err.(type) { // 使用switch对变量err进行类型断言
		case runtime.Error: // 运行时错误
			fmt.Println("runtime error:", err)
		default: // 非运行时错误
			fmt.Println("error:", err)
		}
	}()

	entry() // 对入参函数进行调用,当发生panic时,先调用defer后的闭包,再退出
}

func TestProtect(t *testing.T) {
	fmt.Println("运行前")
	ProtectRun(func() {
		fmt.Println("手动宕机前")

		panic(&panicContext{ // 使用panic手动触发一个错误,并把一个结构体附带信息传入,被ProtectRun函数的recover()捕获
			"手动触发panic",
		})

		fmt.Println("手动宕机后") // panic之后的代码不再执行
	})

	ProtectRun(func() {
		fmt.Println("赋值宕机前")

		var a *int
		*a = 1 // 模拟代码中空指针赋值造成的错误,此时Runtime层抛出错误,被ProtectRun函数的reover()捕获

		fmt.Println("赋值宕机后") // panic之后的代码不再执行
	})

	fmt.Println("运行后")
}

2. panic和recover的关系

  • 有panic没recover,程序宕机
  • 有panic也有recover,程序不会宕机。执行完对应defer后,从宕机点退出当前函数,继续执行代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值