defer 作为延迟函数存在,在函数执行结束时才会正式执行,一般用于资源释放等操作

  参考一段代码https://mp.weixin.qq.com/s/yfH0CBnUBmH0oxfC2evKBA来分析defer 函数压栈操作

package def_test

import (
"fmt"
"testing"
) func GetFn() func() {
fmt.Println("outside")
return func() {
fmt.Println("Inside")
}
} func TestDefer(t *testing.T) {
defer GetFn()()
fmt.Println("Here")
}

  这里实际输出顺序为

outside
Here
Inside

按照代码执行顺序进行分析  

  1. "defer GetFn()()" 在执行这一行代码时,由于defer作为延迟函数存在独立的栈,需要将GetFn()()方法压入栈中,对于 GetFn()函数返回值也是一个函数,因此入栈的函数为GetFn()的返回值;
  2. 为了得到GetFn()的返回值,在defer入栈之前就已经开始执行了GetFn()方法,因此输出了"outside"
  3. 在执行完defer这一行时,继续往后执行"fmt.Println("Here")";
  4. 由于defer真正的执行是在函数返回之前进行调用,在函数返回之前会正式执行defer已入栈的全部方法,输出"Inside"

关于defer 延迟函数调用还有一个重要的点在于参数传递

  1. 对于引用类型传递没有太大的影响,栈中实际保存的是指针指向的地址
  2. 对于值类型数据传递,虽然defer是在函数正式返回前才正式执行调用,但由于其入栈操作是在执行到defer时就已经执行了,此时要传递的值已经复制,对于defer之后的代码对已传入值的数据操作实际是不会影响到defer真正执行时的数据

-------未完待续 剩余函数栈以及return分析

golang defer 以及 函数栈和return的更多相关文章

  1. golang之匿名函数结合defer

    defer语句中的函数会在return语句更新返回值变量后再执行,又因为在函数中定义的匿名函数可以访问该函数包括返回值变量在内的所有变量,所以,对匿名函数采用defer机制,可以使其观察函数的返回值. ...

  2. Golang基础之函数

    golang基础之函数 1.为什么需要函数? 有些相同的代码可能出现多次,如果不进行封装,那么多次写入到程序中,会造成程序冗余,并且可读性降低 2.什么是函数 为完成某些特定功能的程序指令集合称为函数 ...

  3. go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数

    温故知新不忘延迟基础 A "defer" statement invokes a function whose execution is deferred to the momen ...

  4. go 学习笔记之解读什么是defer延迟函数

    Go 语言中有个 defer 关键字,常用于实现延迟函数来保证关键代码的最终执行,常言道: "未雨绸缪方可有备无患". 延迟函数就是这么一种机制,无论程序是正常返回还是异常报错,只 ...

  5. golang defer那些坑

    defer以下几个特性,使用时需要关注下. 即时的参数传递 调用os.Exit()时defer不会被执行 defer与return的先后顺序 1.即时的参数传递 定义defer时传入的参数,是作为拷贝 ...

  6. golang defer 延后执行什么

    对于golang的defer,我们已经知道,defer定义的语句可以延后到函数返回时执行. 经常用在文件的关闭,锁的释放等场景中.而且defer定义的语句即使遇到panic也会执行.这样,可以执行必要 ...

  7. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  8. c函数调用过程原理及函数栈帧分析

    转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...

  9. broadcom6838开发环境实现函数栈追踪

    在嵌入式设备开发中.内核为内核模块的函数栈追踪已经提供了非常好的支持,但用户层的函数栈追踪确没有非常好的提供支持. 在网上收集学习函数栈跟踪大部分都是描写叙述INTER体系架构支持栈帧的实现机制.或者 ...

随机推荐

  1. wsgi的environ变量

    The environ dictionary is required to contain these CGI environment variables, as defined by the Com ...

  2. Eligibility Traces and Plasticity on Behavioral Time Scales: Experimental Support of neoHebbian Three-Factor Learning Rules

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 大多数基本行为,如移动手臂抓住物体或走进隔壁房间探索博物馆,都是在几秒钟的时间尺度上进化的:相反,神经元动作电位则是在几 ...

  3. 区块链入门到实战(22)之以太坊(Ethereum) – 账号(地址)

    作用: 外部账号 – 用户使用的账号,账户余额. 合约账号 – 智能合约使用的账号,每个智能合约都有一个账号,内存和账户余额 以太坊(Ethereum)网络中,有2种账号: 外部账号 – 用户使用的账 ...

  4. js byte字节流和数字,字符串之间的转换,包含无符和有符之间的转换

    var NumberUtil={ //byte数组转换为int整数 bytesToInt2:function(bytes, off) { var b3 = bytes[off] & 0xFF; ...

  5. source insight编辑matlab,不可

    先说结论,我用的source insight版本是4.0x,matlab的语言包用的sourceinght官网提供的matlab.clf.链接如下:https://www.sourceinsight. ...

  6. 遇到doxygen生成的chm文档目录如果有中文是乱码?

    原因不在于doxygen,它没有问题,问题出在微软的HTML Help Workshop的hhc.exe不支持utf8.所以要解决这个问题,需要做两个额外的步骤: 1.将html/index.hhp中 ...

  7. 【Spring】IOC容器注解汇总,你想要的都在这儿了!!

    写在前面 之前,我们在[Spring]专题中更新了不少关于Spring注解相关的文章,有些小伙伴反馈说,看历史文章的话比较零散,经常会忘记自己看到哪一篇了.当打开一篇新文章时,总感觉自己似乎是看到过了 ...

  8. WebApi OAuth2身份认证

    一.什么是OAuth OAuth是一个关于授权(Authorization)的开放网络标准,目前的版本是2.0版.注意是Authorization(授权),而不是Authentication(认证). ...

  9. Java的foreach用法

    foreach其实就是for的加强版,其语法如下: for(元素类型type 元素变量value : 遍历对象obj) { 引用x的java语句; } 举个例子,比如定义一个数组,使用foreach以 ...

  10. 7.SwrContext音频重采样使用

    头文件位于#include <libswresample/swresample.h>   SwrContext常用函数如下所示 SwrContext *swr_alloc(void); / ...