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 会在当前函数返回前执行传入的函数,它会经常被用于关闭文件描述符.关闭数据库连接以及解锁资源. 理解这句话主要在三个方面: 当前函数 返回前执行,当然函数可能没有返回值 传入的函 ...
随机推荐
- postman 8.7.0 下的cookie 禁用
简介:以下过程描述在postman8.7.0中,如何禁用掉cookie,使每次请求都带空cookie去请求服务器. 有一个简单投票场景.投票连接是一个get请求, 类似如http://domain/t ...
- mongodb定时备份
1. https://www.jianshu.com/p/a9352e28e2d6 (未测试) 通过centos 脚步来执行备份操作,使用crontab实现定时功能,并删除指定天数前的备份 具体操 ...
- 关于使用antd-proTable,报错 ResizeObserver loop limit exceeded
错误如上,原因有几种情况 一:columns中,属性又ellipsis属性,但是没有设置width,导致table不知道如何计算在什么时候,开始对内容进行加省略号,出现了计算错误 如 const c ...
- markdown常用语法及Typora的使用
一.markdown markdown简介 markdown是一种文档格式,后缀名为.md.markdown非常适于写博客,基本所有博客网站都支持markdown语法格式. 1.标题 mark ...
- 翟佳:StreamNative 组织构建之路丨声网开发者创业讲堂 • 第 5 期
前言 翟佳,StreamNative 联合创始⼈,Apache Pulsar PMC 成员与 Committer.之前任职于 EMC,担任统⼀存储部⻔技术负责⼈. 在声网开发者创业讲堂 • 第 5 期 ...
- Rainbond PipeLine插件部署与springboot应用部署实践
前言:上一篇介绍额rainbond单机部署+单个节点的k8s环境搭建,本篇介绍rainbond5.12新增的pipeline插件的使用 1.Pipeline插件的安装 安装gitlab与gitlab- ...
- 面试突击:MVCC 和间隙锁有什么区别?
MVCC 和间隙锁是两种完全不同的机制,但它们的目的都是相同的,都是用来保证数据库并发访问的,我们先来看二者的定义. MVCC 定义 MVCC 是多版本并发控制(Multi-Version Concu ...
- 职场「OKR」,魔幻又内卷
个人习惯称之为[O-KR-KPI]组合: 01 从进厂实习那天开始,就接触了KPI的概念: 互联网公司,年初入职,可能因为那天是周五,又赶上月底,少不了要把KPI搬出来折腾一番: 天时,地利,人和: ...
- 基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 1/3
基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 1/3 基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 2/3 基于Go/Grpc/ ...
- abp(net core)+easyui+efcore实现仓储管理系统——ABP升级7.3下(五十九)
Abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...