2020-11-19:go中,defer原理是什么?
福哥答案2020-11-19:
- - 什么是defer
- defer是go语言提供的一种用于注册延迟调用的机制:让函数或者语句在当前函数执行完毕(包括return正常结束或者panic导致的异常结束)之后执行。
- defer语句通常用于一些成对的操作场景,打开/关闭连接,加锁/解锁,打开文件/关闭文件等等
- defer在一些需要回收资源的场景中非常有用
- 为什么需要defer
- 有效防止内存泄漏
- defer底层原理
- 每次defer语句在执行的时候,都会将函数进行“压栈”,函数参数会被拷贝下来。当外层函数退出时,defer函数会按照定义的顺序逆序执行。如果defer执行的函数为nil,那么会在最终调用函数中产生panic。
- 编译器会把 defer 语句翻译成对 deferproc 函数的调用,同时,编译器也会在使用了 defer 语句的 go 函数的末尾插入对 deferreturn 函数的调用。
- 每一个goroutine结构体中都有一个_defer 指针变量用来存放defer单链表。defer保存用什么数据结构?回答栈过不了面试官那关,defer单链表应该能过关。_defer 结构体如下:
- siz:所有传入参数的总大小。
- started:该 defer 是否已经执行过。
- heap:表明该defer是否存储在heap上。
- sp:函数栈指针寄存器,一般指向当前函数栈的栈顶。
- pc:程序计数器,有时称为指令指针(IP),线程利用它来跟踪下一个要执行的指令。在大多数处理器中,PC指向的是下一条指令,而不是当前指令。
- fn:指向传入的函数地址和参数。
- _panic:指向 _panic 链表。
- link:指向 _defer 链表。
- 为什么defer要按照定义的顺序逆序执行:后面定义的函数可能会依赖前面的资源,所以要先执行。如果前面先执行,释放掉这个依赖,那后面的函数就不能找到它的依赖了。
- defer函数定义时,对外部变量的引用方式有两种,分别是函数参数以及作为闭包引用。在作为函数参数的时候,在defer定义时就把值传递给defer,并被cache起来。如果是作为闭包引用,则会在defer真正调用的时候,根据整个上下文云确定当前的值。
- defer后面的语句在执行的时候,函数调用的参数会被保存起来,也就是复制一份。在真正执行的时候,实际上用到的是复制的变量,也就是说,如果这个变量是一个“值类型”,那他就和定义的时候是一致的,如果是一个“引用”,那么就可能和定义的时候的值不一致
- 利用defer原理
- 利用defer先求值,再延迟调用的性质
- defer与return
- defer语句的参数
- defer语句表达式的值在定义的时候就已经确定了
- 闭包:由函数以及相关引用环境组合而成的实例,也就是说闭包=函数+引用环境
- 匿名函数:匿名函数就是我们说的闭包,它不能独立存在,但可以直接调用或者赋值于某个变量。一个闭包,继承了函数声明时的作用域。在go语言中,所有的匿名函数都是闭包
- defer配合recover
- recover:异常捕获,可以让程序在引发panic的时候不会崩溃退出。在引发panic的时候,panic会停掉当前正在执行的程序,但是,在这之前,它会有序的执行完当前goroutine的defer列表的语句。所以我们通常在defer里面挂一个recover,防止程序直接挂掉,类似于try...catch.recover()函数只在defer的上下文中才有效,直接调用,会返回nil
***
[评论,有好几个参考地址](https://user.qzone.qq.com/3182319461/blog/1605740826)
2020-11-19:go中,defer原理是什么?的更多相关文章
- 2018.11.19 Struts2中Action类的书写方式
方式1: 方式2: 方式3
- 布客·ApacheCN 编程/后端/大数据/人工智能学习资源 2020.11
公告 我们始终与所有创作者站在一起,为创作自由而战.我们还会提供一切必要的技术支持. 我们全力支持科研开源(DOCX)计划.希望大家了解这个倡议,把这个倡议与自己的兴趣点结合,做点力所能及的事情. 我 ...
- Notes of Daily Scrum Meeting(11.19)
Notes of Daily Scrum Meeting(11.19) 现在工程项目进入尾声了,我们的项目中还有一些问题需要解决,调试修改起来进度比较慢,所以昨天就没有贴出项目 进度,今天的团队工作总 ...
- Linux中LVM2原理及制作LVM2
Linux中LVM2原理及制作LVM2 一.LVM原理 [MD]:Multi Device 多设备 Mdadm是一个用户空间工具,是RAID的管理工具,与真正的RAID工作没有太大关系.真正的RAID ...
- Linux编译内核 Ubuntu18.04 -2020.11.04
Linux编译内核 Ubuntu18.04 -2020.11.04 关闭虚拟机并备份 首先关闭虚拟机,其次直接找到.vmdk所在目录,并压缩该目录实现备份 下载内核源码 Linux内核官网:https ...
- apiAutoTest-更新2020/11/23
原始版本 简书:https://www.jianshu.com/p/6bfaca87a93b 博客园:https://www.cnblogs.com/zy7y/p/13426816.html test ...
- Goland 2020.2.x 激活码永久破解教程 (最新Goland激活码!2020.11.26亲测可用!)
在2020.11.26 Goland的用户们又迎来了一次更新,这就导致很多软件打开时候就提示Goland激活码已经失效,码小辫第一时间给各位分享了关于最新Goland激活破解教程! goland已经更 ...
- 2020.11最新JAVA环境安装配置
Windows10下java环境配置 更新:2020年11月25日 电脑环境: windows10 64位 一.下载jdk 首先到Oracle网站下载对应操作系统的jdk安装包. https://ww ...
- 智能物联网(AIoT,2020年)(中)
智能物联网(AIoT,2020年)(中) 05 中国AIoT产业图谱 06 中国AIoT商业模式 标准程度越低人力和时间成本投入越多,2B2C模式附加值高 07 中国AIoT玩家分布简介 四类玩家,优 ...
- 2. Go中defer使用注意事项
1. 简介 defer 会在当前函数返回前执行传入的函数,它会经常被用于关闭文件描述符.关闭数据库连接以及解锁资源. 理解这句话主要在三个方面: 当前函数 返回前执行,当然函数可能没有返回值 传入的函 ...
随机推荐
- TP5.0--5.1获取当前域名的方法
TP5.0获取当前域名的方法 use think\Request; $request = Request::instance(); $domain = $request->domain(); 获 ...
- Web For Pentester File include
File include(文件包含) Example 1 没有任何过滤 审计源码 没有对我们传参的page进行任何过滤,payload如下 http://172.16.1.104/fileincl/e ...
- GUI编程实战--贪吃蛇
GUI编程实战--贪吃蛇 参考:遇见狂神说 https://space.bilibili.com/95256449 界面绘制 帧:如果时间片足够小,就是动画,一秒30帧.连起来是动画,拆开是静态的图片 ...
- leader epoch
更多内容,前往 IT-BLOG leader epoch 代表 Leader 的纪元信息(epoch),初始值为0.每当 Leader 变更一次,leader epoch 的值就会加1,相当于为 Le ...
- rocketMq和kafka对比
为什么在RocketMQ和kafka中选型 在单机同步发送的场景下,Kafka>RocketMQ,Kafka的吞吐量高达17.3w/s,RocketMQ吞吐量在11.6w/s. kafka高性能 ...
- Vue2数据驱动渲染(render、update)
上一篇文章我们介绍了 Vue2模版编译原理,这一章我们的目标是弄清楚模版 template和响应式数据是如何渲染成最终的DOM.数据更新驱动视图变化这部分后期会单独讲解 我们先看一下模版和响应式数据是 ...
- 在已有的vue项目中添加单元测试模块
package.json 添加新命令 "test": "jest",下载包: "jest": "^26.6.3", &q ...
- GaussDB(DWS)网络调度与隔离管控能力
摘要:调度算法是调度器的核心,设计调度算法要充分考虑业务场景和用户需求,没有万能的调度算法,只有合适的调度算法. 本文分享自华为云社区<GaussDB(DWS)网络调度与隔离管控能力>,作 ...
- kubernetes 启用 PHP + Nginx 网页环境
kubernetes 启用 PHP + Nginx 网页环境 传统安装方式进行安装步骤较多,使用kubernetes可以实现快速启用环境,在测试或者线上都可以做到快速 启用 编写 yaml 文件 [r ...
- [PKM] 家庭数据中心
1 NAS(Network Attached Storage/网络附属存储) 1.1 NAS的定义 NAS(Network Attached Storage:网络附属存储):具备资料存储功能的装置.按 ...