golang中defer和return的顺序

被这个坑搞得有点惨。查了些资料,特此记录下。

在golang中,如果在defer 中操作返回数,往往会比较头晕。

例1:

 func f1() (i int) {

  i = 1

  defer func(){

     i++ 

  }

  return i

}

 

要点:

return是分为两步执行的,第一步赋值给返回值,第二步真正的返回到函数外部。而defer是在第一步之后执行。

所以,例1中,“return i”其实是把 i赋值给返回值i(当然,这里return的值就是i,所以其实没有赋值),此时i=1,然后再执行 defer,i=2,返回的i最终值是2。

例2:

func f2() int {
    i := 1
    defer func(){i++}()

    return i

}

例2这里,“return i”把i=1赋值给返回值,但是这里的返回值没有显示声明,会生成一个临时变量,假设叫‘tmp’,即tmp=1。然后,执行defer的时候,i=2。但是这个和'tmp'没关系。所以最终返回的是1。

例3:

func f2() *int {
    i := 1
    defer func(){i++}()

    return &i

}

例3这里,“return &i”把i的地址赋值给返回值,同样是临时变量‘tmp *int’。即,真正返回的是i的地址*tmp。然后,执行defer的时候,对tmp指针没操作,但是tmp指向的那个值(即i),修改成了2。所以,如果对返回的指针取值,结果是2。和传址参数一样理解。

 

综上,如果是显式命名的返回值,则defer中可以对其操作。如果是非显式命名的返回值,则返回时会新定义一个返回变量,defer操作不到。当然,指针变量。。。为所欲为!

posted @ 2020-08-31 21:06  _zxq  阅读(1157)  评论(0编辑  收藏  举报