概述
defer 执行时机
defer 执行是在编译阶段确定的, 没有其他好办法, 只能查阅编译后的代码来找到答案;
go tool compile -S -N -l cmd.go > cmd.s
defer 关键字经过编译器,涉及两主要数据结构
runtime.deferprocStack 构建defer函数数据结构,runtime.deferreturn 取defer函数并调用。那么分析一下defer 调用时机
....
....
0x0097 00151 (cmd.go:9) XCHGL AX, AX
0x0098 00152 (cmd.go:9) CALL runtime.deferreturn(SB) 执行defer函数链
0x009d 00157 (cmd.go:9) MOVQ 136(SP), BP 还原BP指针
0x00a5 00165 (cmd.go:9) ADDQ $144, SP 释放栈
0x00ac 00172 (cmd.go:9) RET 返回
....
....
可见return 并不是原子指令,包含执行defer函数链步骤,还原BP指针步骤,释放栈步骤,返回步骤;所以defer是在 return 之后执行的;