一文掌握Golang的panic和recover实战

 更新时间:2024年09月10日 15:48:17   作者:CodeJR  
Go语言中,异常处理通常依赖error返回值,本文将通过示例展示如何在Go语言中正确使用recover来处理panic异常,防止程序直接崩溃,感兴趣的朋友跟随小编一起看看吧

简述

我们都知道在Go语言中的异常处理是通过方法返回error,然后在调用方法处接收error并处理,这里的error通常是使用在业务异常的处理。

如果程序发生数组越界、空指针等异常就不会再通过error来处理,而是通过panic直接报错并终止程序和打印出堆栈信息。那么如何在程序发生panic的时候去处理这个异常而不是终止程序呢?这个时候就需要使用到recover,recover可以捕获到panic异常,并恢复程序的运行。

panic

  • 调用panic后立即终止执行当前函数的剩余代码,在当前goroutine中执行当前函数所有的defer
  • panic只会触发当前goroutine的defer

recover

  • 调用recover可以捕获panic的异常,并恢复程序的执行
  • recover只在defer延迟函数中调用才会生效

实战

示例1

我们首先在代码中直接使用recover捕获异常,并使用panic手动抛出一个异常,看看程序会怎么样

func main() {
	test()
	fmt.Println("main")
}
func test() {
	if err := recover(); err != nil {
		fmt.Println("recover: ", err)
	}
	panic("error")
}

运行上面的代码之后可以从输出看到在test函数中发生了panic,并且直接终止运行,导致main函数中的打印也没有生效,这是因为在前面的时候有讲到过,recover必须在defer延迟函数中调用才会生效。

panic: error                                                    
goroutine 1 [running]:                                          
main.test()                                                     
        C:/Users/lee/GolandProjects/test/main.go:33 +0x30
main.main()                                                     
        C:/Users/lee/GolandProjects/test/main.go:24 +0x13

示例2

修改上面的代码,将recover放到defer延迟函数中调用:

func main() {
	test()
	fmt.Println("main")
}
func test() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("recover: ", err)
		}
	}()
	panic("error")
}

这个时候我们再次运行代码,可以看到虽然在test函数中发生了panic,但是程序并没有终止运行,而是被defer中的recover捕获到了异常并恢复运行,同时main函数中的print也正常打印。

recover:  error
main

示例3

上面示例2中将recover是放到defer的函数中调用,那么如果在defer后面直接调用recover会生效吗?使用下面代码进行测试。

func main() {
	test()
	fmt.Println("main")
}
func test() {
	defer recover()
	panic("error")
}

运行上面的代码之后发现在defer后面直接调用recover是无效的,程序照样会发生异常并终止运行,所以**recover必须是在defer的延迟函数中调用才会生效。**示例2中是匿名延迟函数,如果使用具名延迟函数同样有效。

panic: error
goroutine 1 [running]:
main.test()
        C:/Users/lee/GolandProjects/test/main.go:30 +0x58
main.main()
        C:/Users/lee/GolandProjects/test/main.go:24 +0x13

示例4

上面说到过recover必须在defer的延迟函数中调用,那下面的代码可以生效吗?

func main() {
	test()
	fmt.Println("main")
}
func test() {
	defer func() {
		defer recover()
	}()
	panic("error")
}

运行上面的代码可以看到recover是生效的,recover函数被一个延迟函数调用,且recover函数本身作为一个延迟函数,这个情况下也是可以正常捕获panic异常的,程序运行如下:

main

到此这篇关于一文掌握Golang的panic和recover的文章就介绍到这了,更多相关Golang panic和recover内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang Mutex互斥锁源码分析

    Golang Mutex互斥锁源码分析

    本篇文章,我们将一起来探究下Golang Mutex底层是如何实现的,知其然,更要知其所以然。文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-10-10
  • Go语言如何轻松编写高效可靠的并发程序

    Go语言如何轻松编写高效可靠的并发程序

    这篇文章主要为大家介绍了Go语言轻松编写高效可靠的并发程序实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Goland 的安装及激活教程(window、linux下安装)

    Goland 的安装及激活教程(window、linux下安装)

    这篇文章主要介绍了Golang Goland 的安装及激活详细教程,包括window下安装goland和linux下安装goland,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Golang解析yaml文件操作指南

    Golang解析yaml文件操作指南

    之前一直从事java开发,习惯了使用yaml文件的格式,尤其是清晰的层次结构、注释,下面这篇文章主要给大家介绍了关于Golang解析yaml文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Go 防止 goroutine 泄露的方法

    Go 防止 goroutine 泄露的方法

    Go 的并发模型与其他语言不同,虽说它简化了并发程序的开发难度,但如果不了解使用方法,常常会遇到 goroutine 泄露的问题。本篇主要从如何写出正确代码的角度来介绍如何防止 goroutine 的泄露,需要的朋友可以参考下
    2019-09-09
  • Golang Makefile示例深入讲解使用

    Golang Makefile示例深入讲解使用

    一次偶然的机会,在 github 上看到有人用 Makefile,就尝试了一下,发现真的非常合适,Makefile 本身就是用来描述依赖的,可读性非常好,而且与强大的 shell 结合在一起,基本可以实现任何想要的功能
    2023-01-01
  • go语言实战之实现比特币地址校验步骤

    go语言实战之实现比特币地址校验步骤

    这篇文章主要介绍了go语言实战之实现比特币地址校验步骤,利用生产的随机数采用椭圆加密算法生成公钥,具体步骤实例代码请参考下本文
    2021-05-05
  • Go panic的三种产生方式细节探究

    Go panic的三种产生方式细节探究

    这篇文章主要介绍了Go panic的三种产生方式细节探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 简单四步快速集成go环境变量

    简单四步快速集成go环境变量

    这篇文章主要为大家介绍了快速集成go环境变量的简单四个步骤详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Go Println和Printf的区别详解

    Go Println和Printf的区别详解

    这篇文章主要介绍了Go Println和Printf的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12

最新评论