跳到主要内容

Go defer 详解

· 阅读需 4 分钟
ahKevinXy

基本功能介绍

  1. defer是一种延迟处理机制,是在函数进行return之前进行执行。
  2. defer是采用栈的方式执行,也就是说先定义的defer后执行,后定义的defer最先被执行。

扩展

  1. defer 执行顺序 . 采用栈的方式执行,先定义先执行
  2. defer 与 return 谁先谁执行 return 之后的语句先执行,defer 后的语句后执行。
  3. 函数的返回值初始化与 defer 间接影响。defer中修改了返回值,实际返回的值是按照defer修改后的值进行返回
  4. defer 遇见 panic。按照defer的栈顺序,输出panic触发之前定义好的defer
  5. defer 中包含 panic。按照defer的栈顺序,输出panic触发之前的defer。并且defer中会接收到panic信息。
  6. defer 下的函数参数包含子函数。会先进行子函数的结果值,然后在按照栈的顺序进行输出

defer 与panic

panic是Go语言中的一种异常现象,它会中断程序的执行,并抛出具体的异常信息

当函数中发生了panic异常,会马上中止当前函数的执行,panic之前定义的defer都会被执行,所有的 defer 语句都会保证执行并把控制权交还给接收到 panic 的函数调用者。这样向上冒泡直到最顶层,并执行(每层的) defer,在栈顶处程序崩溃,并在命令行中用传给 panic 的值报告错误情况:这个终止过程就是 panicking。

defer中包含panic

程序中虽然发生了panic,但是在panic之前定义的defer语句,还是会被执行。要想在defer中获取到具体的panic信息,需要使用 recover() 进行获取。

这个(recover)内建函数被用于从 panic 或 错误场景中恢复:让程序可以从 panicking 重新获得控制权,停止终止过程进而恢复正常执行。

defer下的函数参数包含子函数

  1. 执行第1个defer时,压入defer栈中,该defer会执行一个function的函数,在函数返回之前执行
  2. 因为该函数中又包含了一个函数(子函数),Go语言处理的机制是,先执行该子函数。
  3. 执行完子函数,接着再执行第2个defer语句。此时,第2个defer中也有一个子函数,按照第2点的逻辑,这个子函数会被直接执行
  4. 定义完defer语句之后,此时结束该函数的调用。所有被定义的defer语句,按照栈顺序进行输出

当defer中存在子函数时,子函数会按照defer定义的语句顺序,优先执行。defer最外层的逻辑,则按照栈的顺序执行。

标签: