recover 没有捕获异常_golang 的异常处理(Panic和Recover)

Panic和Recover

Go没有像Java那样的异常机制,它不能抛出异常,而是使用了panic和recover机制。一定要记住,你应当把它作为最后的手段来使用,也就是说,你的代码中应当没有,或者很少有panic的东西。这是个强大的工具,请明智地使用它。那么,我们应该如何使用它呢?

Panic

是一个内建函数,可以中断原有的控制流程,进入一个令人恐慌的流程中。当函数F调用panic,函数F的执行被中断,但是F中的延迟函数会正常执行,然后F返回到调用它的地方。在调用的地方,F的行为就像调用了panic。这一过程继续向上,直到发生panic的goroutine中所有调用的函数返回,此时程序退出。恐慌可以直接调用panic产生。也可以由运行时错误产生,例如访问越界的数组。

Recover

是一个内建的函数,可以让进入令人恐慌的流程中的goroutine恢复过来。recover仅在延迟函数中有效。在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。如果当前的goroutine陷入恐慌,调用recover可以捕获到panic的输入值,并且恢复正常的执行。

下面这个函数演示了如何在过程中使用panicvar user = os.Getenv("USER")

func init() {

if user == "" {

panic("no value for $USER")

}

}

下面这个函数检查作为其参数的函数在执行时是否会产生panic:func throwsPanic(f func()) (b bool) {

defer func() {

if x := recover(); x != nil {

b = true

}

}()

f() //执行函数f,如果f中出现了panic,那么就可以恢复回来

return

}

最容易理解就是给个例子,文章里有例子:package main

import (

"fmt"

//"os"

)

var user = ""

func inita() {

defer func() {

fmt.Print("defer##\n")

}()

if user == "" {

fmt.Print("@@@before panic\n")

panic("no value for user\n")

fmt.Print("!!after panic\n")

}

}

func throwsPanic(f func()) (b bool) {

defer func() {

if x := recover(); x != nil {

fmt.Print(x)

b = true

}

}()

f()

fmt.Print("after the func run")

return

}

func main() {

throwsPanic(inita)

}

执行结果:D:\go>go run b.go

@@@before panic

defer##

no value for user

如上面所说的:

panic在user=""时,打断了函数的执行,fmt.Print("!!after panic\n")没有执行。 但函数中的延迟函数会正常执行,打印了 defer##。然后返回到调用该函数的地方,继续上面的过程。

直到执行完所有函数的defer,退出程序。Recover可以捕获到panic的值,上面的打印no value for user。并且恢复正常的执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值