defer


func f1() int {     x := 5     defer func() {         x++     }()     return x }
func f2() (x int) {     defer func() {         x++     }()     return 5 } func main() {
    fd := f1()     fmt.Printf("fd: %v\n", fd)     haha := f2()     fmt.Printf("haha: %v\n", haha) }   分别看看f1和f2的汇编 f1:

 f1的返回值是匿名的 所以开辟内存的时候x的内存地址是0x10,匿名返回值的变量是0x8,开辟了两个变量内存

 这里就是先赋值,把0x10中的值给了0x8,然后执行到call defer处 进入defer func

 汇编中的返回值都是放在EAX中的, 但是可以看见AX的值来自0x8(DX),我其实也不想跟的太深入,因为看不到内存和栈的信息,想看看0x8(DX)的值都看不了,

 向上找,可以看到lea 0x10(SP),DX ,把地址给了DX,DX中存放着X的地址,于是上上图中就自增1,改变的是x的值

这个时候x的0x10(sp)=6,匿名变量0x8(sp)还是等于5 

 最后取出0x8(sp)中的值放入ax中返回

f2:

 这里是指定了返回值x,所以就只需要开辟了x的内存,

 保存地址

自增1  返回到上层函数 取值 返回

 至于为什么f1和f2在自增的时候都是通过0x8(dx)得到的值,没深入跟,也不好跟,但肯定是在某个地方有处理,当前只能通过DX来判断 地址存入的寄存器,

所以就简单的总结下:

当返回值是匿名变量的时候,会开辟匿名变量的内存,真正返回的时候也是返回的这个匿名变量的值,因为是匿名的所以无法对它修改,

x:=5,return x, defer fun(){x++},x=5,return时赋值给匿名变量,x++后x=6 ,匿名变量还是5,返回的是匿名变量

当返回值不是匿名变量的时候,会直接开辟这个变量的内存,返回的时候也是为这个变量赋值,在defer func在函数内改变的也是这个变量,

Go