zoukankan      html  css  js  c++  java
  • Go 彻底弄懂return和defer的微妙关系

    package main
     
    import "fmt"
     
    func main()  {
        fmt.Println("f1 result: ", f1())
        fmt.Println("f2 result: ", f2())
    }
     
    func f1() int {
        var i int
        defer func() {
            i++
            fmt.Println("f11: ", i)
        }()
     
        i = 1000
        return i
    }
     
    func f2() (i int) {
        defer func() {
            i++
            fmt.Println("f21: ", i)
        }()
        i = 1000
        return i
    }

    f1函数:

      进入该函数,因为没有指定返回值变量,需要先声明i变量,因为是int类型,如果没有赋值,该变量初始化值为0,之后执行i=1000的赋值操作,然后执行return语句,返回i的值。

      真正返回之前还要执行defer函数部分,两个defer函数分别针对i进行自增操作,i的值依次为1001和1002

    f2函数:

      进入该函数,因为已经定义好了返回值变量即为i,然后直接赋值i=1000,再返回i的值。

      同样的,也要在真正返回i前,执行两个defer函数,同样i依次自增得到1001和1002。

      问题的关键是为什么无名参数返回的值是1000,其并未收到defer函数对于i自增的影响;而有名函数在执行defer后,最后返回的i值为1002。

    原因就是return会将返回值先保存起来,对于无名返回值来说,
    保存在一个临时对象中,defer是看不到这个临时对象的;
    而对于有名返回值来说,就保存在已命名的变量中。

  • 相关阅读:
    Linux命令之more
    Linux命令之sort
    STM32启动模式
    poll调用深入解析
    STM32 控制步进电机 28BYJ-48
    NEC协议
    家用宽带的上传和下载速度
    Ubuntu14.04更新源
    波特率和比特率【串口为例】
    CentOS: make menuconfig error: curses.h: No such file or directory
  • 原文地址:https://www.cnblogs.com/forgo/p/13490720.html
Copyright © 2011-2022 走看看