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. SpringMVC使用Session

    Session在用户登录,一些特殊场合在页面间传递数据的时候会经常用到 @ 目录 修改IndexController check.jsp 效果 修改IndexController 映射 /check ...

  2. MySQL经典练习题及答案,常用SQL语句练习50题

    表名和字段 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id,c_name,t_id ...

  3. LeetCode 92 | 大公司常考的面试题,翻转链表当中指定部分

    今天是LeetCode专题的第58篇文章,我们一起来看看LeetCode 92题,翻转链表II(Reverse LInked List II). 这题的官方难度是Medium,2451个赞同,145个 ...

  4. Intelligence Beyond the Edge: Inference on Intermittent Embedded Systems

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 以下是对本文关键部分的摘抄翻译,详情请参见原文. Abstract 能量收集技术为未来的物联网应用提供了一个很有前景的平台.然而,由于这些 ...

  5. CODING DevOps 代码质量实战系列第一课:代码规范与 Git Flow

    讲师介绍 杨周 CODING DevOps 架构师 CODING 布道师 连续创业者.DIY/Linux 玩家.知乎小 V,曾在创新工场.百度担任后端开发.十余年一线研发和带队经验,经历了 ToB.T ...

  6. Excel—TIME函数简介与用法

    问题场景 算员工饱和度时,需要从实际考勤打卡时间中减去午休时间1.5个小时: 导出的时间时分秒是分开的,连接时分秒. 场景一 计算员工饱和度,需要减去午休时间,用下班打卡时间减去午休的1.5小时算出的 ...

  7. .Net ImageSharp给图片添加文字

    开始之前需要Nuget安装的包 ##这三个包是一定要安装的,不然库的有些方法用不了 一.导入字体 var fonts = new FontCollection(); var fontFamily = ...

  8. react 有没有类似vue中watch这样的api?

    就是 当组件里state 里的数据发生变化可以监听到这个数据的变化 当数据发生变化的时候做一些事情 比如ajax请求 ?初学react 用vue的时候会用watch 和computed 去监听数据发生 ...

  9. el-select 封装

    这里打算封装一个全局el-select组件 MySelect.vue <template> <el-select v-if="options.length!==0" ...

  10. css实例——“旋转”太极八卦图

    话不多说,直接上代码: HTML代码部分: <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...