【golang】多个defer的执行顺序以及其相关练习

打印 上一主题 下一主题

主题 921|帖子 921|积分 2763

前言
  做了几道关于defer的测试题,吓了一大跳,感觉自己之前的理解有些问题,所以写下这篇博客,加深下印象。
正文:
  多个defer的执行顺序:
   先进后出,类似于栈的特性。
  下面我们来测试下:
  1.defer 与 panic:
    
  1. func deferAndPanic() {
  2.     defer func() { fmt.Println("defer1") }()
  3.     defer func() { fmt.Println("defer2") }()
  4.     defer func() { fmt.Println("defer3") }()
  5.     panic("异常内容")
  6. }
  7. func main() {
  8.     deferAndPanic()
  9.     fmt.Println("main 正常结束")
  10. }
复制代码
结果分析:defer遇到panic会强制出栈,这个时候的结果为 :
  
 
 2.defer与panic+recover
  如果我们对panic进行了recover呢?
  1. [/code]func deferAndPanic() {
  2.         defer func() { fmt.Println("defer1") }()
  3.         defer func() { fmt.Println("defer2") }()
  4.         defer func() { fmt.Println("defer3") }()
  5.         defer func() {
  6.                 if err := recover(); err != nil {
  7.                         fmt.Println("被捕获err=", err)
  8.                 }
  9.         }()
  10.         panic("异常内容")
  11.         fmt.Println("--------------------------")
  12. }
  13. [code] 
复制代码
结果解析: 这个时候程序进行捕获后会回到之前程序的调用处后,继续执行。但是panic后面的语句不会执行。
看下执行结果:
  
 
 3.defer与函数嵌套调用
 看个例子:
  
  1. func function(index int, value int) int {
  2.     fmt.Println(index)
  3.     return index
  4. }
  5. func main() {
  6.     defer function(1, function(3, 0))
  7.     defer function(2, function(4, 0))
  8. }
复制代码
结果分析:
  1.第一个defer压入栈的时候需要将他所有信息包括参数一同压入,所以会对内部的函数进行计算,得到最终值然后入栈。第二个defer同理。
  2.这样最后结果返回的就是:

 
 是不是有点惊讶!博主也是看到这些例子,才觉得自己对defer的了解浮于表面了~
 
总结:
  defer遇到panic会强制出栈,至于panic的内容,需要看是否有捕获程序。
  defer遇到嵌套函数的调用,入栈的时候需要先解析出来该内部函数的值,再压入栈内
|不骄不躁,保持学习

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

科技颠覆者

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表