GO语言defer和return 的执行顺序

defer和return的执行顺序探究

先来看一段代码

package main

import (
    "fmt"
)

func f() int{
    var i int
    defer func(){
        i++
    }()
    return i    
}

func f2() (i int){
    defer func(){
        i++
    }()
    return i    
}

func main() {
    fmt.Println(f())
    fmt.Println(f2())
}

上面的程序输出结果是啥呢?答案是:0 1
你答对了嘛?
这里面涉及到的就是defer和return 执行顺序的关系。
我们先来探究一下defer执行的顺序。

defer 的执行顺序是按照先声明后执行的栈顺序执行。来个例子

package main

import (
    "fmt"
)

func main() {
    defer func(){
        fmt.Println("f1")
    }()
    
    defer func(){
        fmt.Println("f2")
    }()
    
    fmt.Println("Hello fudan!")
}

执行结果为:
Hello fudan!
f2
f1
所以大家通过这个例子应该知道了defer的执行顺序,那如果多个defer之间多了几个语句呢?
再来看一个例子:

package main

import (
    "fmt"
)

func main() {
    defer func(){
        fmt.Println("f1")
    }()
    
    fmt.Println("You")
    
    defer func(){
        fmt.Println("f2")
    }()
    
    fmt.Println("Me")
    
    fmt.Println("Hello fudan!")
}

执行结果是:
You
Me
Hello fudan!
f2
f1
如果上面两个例子都明白了,那defer基本就大概知道是什么原理了。那接下来来看一下return 的基本执行过程吧。

return 的基本执行过程

我们知道go中的函数返回值有匿名和有名两种。

  • 对于匿名的可以理解成执行return 语句的时候,分成两步,第一步需要设置一个临时变量s用来接收返回值,第二步将临时变量s返回。
  • 对于有名的可以理解成执行return的时候,直接将变量返回。

而我们知道,所有的defer都将在真正的return 变量之前运行,所以对于上面两种情况,defer对于返回值的影响也有两种:

  • 对于匿名的:第一步设置临时变量保存返回值,第二步按照defer的执行步骤执行defer语句,如果其中有对变量的修改,将不会影响s变量的值。
  • 对于有名的:第一步先执行defer,对变量进行修改,第二步,返回被修改的返回值。

所以,理解了上面的步骤的之后,我们就可以理解开头的函数了:

package main

import (
    "fmt"
)

func f() int{
    var i int
    defer func(){
        i++
    }()
    return i    
}

func f2() (i int){
    defer func(){
        i++
    }()
    return i    
}

func main() {
    fmt.Println(f())
    fmt.Println(f2())
}

分析:
执行return 的时候,

  • f函数先通过临时变量s保存i的值,此时i为0,所以s=0, 然后执行defer,修改i的值,i变为1,最后返回s的值,因为s=0, 所以返回值是0;
  • 而f2是有名函数,所以执行return 的时候,i被设置为1,然后真正的返回i值,所以返回的是1.

所以最后的执行结果为:0 1

好了,关于defer和return 就先讲到这了。加油加油!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小吴同学GOGOGO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值