Golang defer 使用及面试常见的坑

前言

defer是Golang中一个常用的关键字,通常用来做一些收尾工作。比如开启了一个东西,就顺手defer中关闭。对于面试,defer也算一个高频考点,尤其是他的许多个坑,因此本文主要复习一下defer的用法

在这里插入图片描述

多个defer的执行顺序

通常来说,defer是在程序的最后才执行。当多个defer出现时,遵循 栈 的先入后出顺序执行。

前言

defer是Golang中一个常用的关键字,通常用来做一些收尾工作。比如开启了一个东西,就顺手defer中关闭。对于面试,defer也算一个高频考点,尤其是他的许多个坑,因此本文主要复习一下defer的用法

多个defer的执行顺序

通常来说,defer是在程序的最后才执行。当多个defer出现时,遵循 栈 的先入后出顺序执行。

在这里插入图片描述

deferreturn一起使用

关于deferreturn的执行顺序,普遍来说是先returndefer,可以参考此例。(直接cv一个,懒得写了)。

package mainimport "fmt"func deferFunc() int {fmt.Println("defer func called")return 0
}func returnFunc() int {fmt.Println("return func called")return 0
}func returnAndDefer() int {defer deferFunc()return returnFunc()
}func main() {returnAndDefer()
}————————————————
原文作者:刘丹冰Aceld
转自链接:https://learnku.com/articles/42255
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。

执行结果
return func called
defer func called

此篇文章中是分了多点来概述此情况——
“知识点 2: defer 与 return 谁先谁后”,
“知识点 3:函数的返回值初始化”,
“知识点 4: 有名函数返回值遇见 defer 情况”

但我认为这样理解下来较为复杂,因此参考了此文,从return的角度来理解,将其归纳在一起。

return并不是原子操作,而是分为:赋值、返回 两个步骤。
加上defer,三者的执行时机则是:赋值、defer、return。

不带命名返回值

因此对应来看,对于“不带命名返回值”的情况,即func test() int这样的情况,由于return的值相当于是编译器自己新建的一个var tmp int,而defer中进行赋值操作则不会影响tmp,因此不影响返回值。

package mainimport "fmt"func main() {t := test()fmt.Println(t)
}func test() int { //无名返回i:=9defer func() {i++fmt.Println("defer1=", i)}()defer func() {i++fmt.Println("defer2=", i)}()return i
} 作者:蓝色记忆
链接:https://juejin.cn/post/7095631673865273352
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

此例中,输出内容是:

defer2= 10
defer1= 11
9 

可以理解为,系统var tmp int,这个tmp是需要返回的值,他是9。但是defer修改的是i,所以互不干涉。

有名返回值

对于有名返回值的情况,由于有名,所以没有了var tmp int这一步,defer中执行的修改会影响return的值,因此会影响。

defer配合panicrecover

参考此文

参考资源

https://learnku.com/articles/42255

https://juejin.cn/post/7095631673865273352

https://juejin.cn/post/7304183399885996067

deferreturn一起使用

关于deferreturn的执行顺序,普遍来说是先returndefer,可以参考此例。(直接cv一个,懒得写了)。

package mainimport "fmt"func deferFunc() int {fmt.Println("defer func called")return 0
}func returnFunc() int {fmt.Println("return func called")return 0
}func returnAndDefer() int {defer deferFunc()return returnFunc()
}func main() {returnAndDefer()
}————————————————
原文作者:刘丹冰Aceld
转自链接:https://learnku.com/articles/42255
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。

执行结果
return func called
defer func called

此篇文章中是分了多点来概述此情况——
“知识点 2: defer 与 return 谁先谁后”,
“知识点 3:函数的返回值初始化”,
“知识点 4: 有名函数返回值遇见 defer 情况”

但我认为这样理解下来较为复杂,因此参考了此文,从return的角度来理解,将其归纳在一起。

return并不是原子操作,而是分为:赋值、返回 两个步骤。
加上defer,三者的执行时机则是:赋值、defer、return。

不带命名返回值

因此对应来看,对于“不带命名返回值”的情况,即func test() int这样的情况,由于return的值相当于是编译器自己新建的一个var tmp int,而defer中进行赋值操作则不会影响tmp,因此不影响返回值。

package mainimport "fmt"func main() {t := test()fmt.Println(t)
}func test() int { //无名返回i:=9defer func() {i++fmt.Println("defer1=", i)}()defer func() {i++fmt.Println("defer2=", i)}()return i
} 作者:蓝色记忆
链接:https://juejin.cn/post/7095631673865273352
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

此例中,输出内容是:

defer2= 10
defer1= 11
9 

可以理解为,系统var tmp int,这个tmp是需要返回的值,他是9。但是defer修改的是i,所以互不干涉。

有名返回值

对于有名返回值的情况,由于有名,所以没有了var tmp int这一步,defer中执行的修改会影响return的值,因此会影响。

defer配合panicrecover

参考此文

参考资源

https://learnku.com/articles/42255

https://juejin.cn/post/7095631673865273352

https://juejin.cn/post/7304183399885996067

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/614518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB聚合:$count

$count阶段用于统计管道中文档的数量。 语法 { $count: <string> }<string> 是文档计数输出字段的名称。<string>必须是非空字符串&#xff0c;不能以$开头&#xff0c;也不能包含.字符。 $count阶段相当于下面$group$project聚合序列&#xff1a; db.co…

数谷·企声|贵州空港智能科技:以“智”提“质”,助力贵阳智慧机场建设

当前&#xff0c;我国民航正大力推进“平安、绿色、智慧、人文”的四型机场建设。贵州空港智能科技有限公司&#xff08;下称“空港智能科技”&#xff09;作为贵州民航产业集团有限公司&#xff08;下称“民航产业集团”&#xff09;信息化建设的排头兵和主力军&#xff0c;近…

Unity组件开发--长连接webSocket

1.下载安装UnityWebSocket 插件 https://gitee.com/cambright/UnityWebSocket/ 引入unity项目&#xff1a; 2.定义消息体结构&#xff1a;ExternalMessage和包结构Package&#xff1a; using ProtoBuf; using System; using System.Collections; using System.Collections.Ge…

Springboot使用自带Logback 与 整合log4j 和 log4j2过程详解

logback 1、添加依赖 <!--spring boot依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>2、logback-spring.xml配置 <?xml version"1.0&…

个人事务备忘录管理微信小程序

介绍 UniApp是一款使用Vue.js开发所有前端应用的框架&#xff0c;能够同时在iOS、Android、H5、小程序等多个平台上运行&#xff1b;所以本系统可以是一个安卓app&#xff0c;也可以是微信小程序 系统包括以下功能&#xff1a; 备忘录 管理个人事务 记事本 事务分类 日记编写…

springboot整合jasypt对yml配置文件密码加密

1.引入依赖 <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.0</version></dependency><dependency><groupId>com.github.ulisesbocc…

CSS水平垂直居中(最常见的三种方案flex、grid、absolute)

本文简单介绍一下现代 CSS 中最常见的三种水平垂直居中方案。 html&#xff1a; <div class"container"><div class"content"></div> </div>css&#xff1a; .container {width: 500px;height: 500px;border: 1px solid #000;.…

Java list 方法分组

在 Java 中&#xff0c;可以使用 List 的 stream() 方法来对列表进行操作。要按照特定条件将元素分组&#xff0c;可以使用 Collectors.groupingBy() 方法。 下面是一个示例代码&#xff0c;展示了如何根据某个属性值将 List 中的元素分组&#xff1a; import java.util.*; im…

JAVA面试部分——后端-线程后篇

3.12 如果在运行当中&#xff0c;遇到线程不够了&#xff0c;会以什么样的方式创建线程 线程池在运行过程中&#xff0c;如果遇到线程不够的情况&#xff0c;会根据线程池的类型和配置进行不同的处理&#xff1a; 对于固定大小的线程池&#xff1a;如果线程因异常结束&#xff…

全网第一篇教你怎么总结多线程知识

于「全景图」&#xff0c;我之前也有一直在构建&#xff0c;可是因为知识储备不够&#xff0c;确实很难构建出来。稍微了解过并发领域知识的人都知道&#xff0c;里面的知识点、概念多而散&#xff1a;线程安全、锁、同步、异步、阻塞、非阻塞、死锁、队列(为什么并发要跟队列扯…

安卓Android Studio读写MifareOne M1 IC卡源码

本示例使用的发卡器&#xff1a; https://item.taobao.com/item.htm?id615391857885&spma1z10.5-c-s.w4002-21818769070.11.66af789eLeok2R <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout …

回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CPO-BP回归基于冠豪猪优化算法[24年新…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子详情实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

【排序算法】三、选择排序(C/C++)

「前言」文章内容是排序算法之选择排序的讲解。&#xff08;所有文章已经分类好&#xff0c;放心食用&#xff09; 「归属专栏」排序算法 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 选择排序1.1 原理1.2 代码实现&#xff08;C/C&#xff09;1.3 优化1.3 特性总结 选择排…

Unity Meta Quest 一体机开发(十三):【手势追踪】自定义交互事件 EventWrapper

文章目录 &#x1f4d5;教程说明&#x1f4d5;交互事件概述&#x1f4d5;自定义交互逻辑⭐方法一&#xff1a;Inspector 面板赋值⭐方法二&#xff1a;纯代码处理 此教程相关的详细教案&#xff0c;文档&#xff0c;思维导图和工程文件会放入 Spatial XR 社区。这是一个高质量…

cuda12.0 安装 pytorch

前两天买的y7000p到了&#xff0c;然后就要重新配下环境。 流程如下 首先下载miniconda &#xff0c;我下的是python3.8的创建自己的自定义环境检查自己的cuda版本&#xff0c;我的是cuda:12.0然后再pytorch上找到对应cuda版本的进行下载&#xff0c;pip install或者conda in…

工作每天都在用的 DNS 协议,你真的了解么?

我们经常访问一些网址的时候&#xff0c;浏览器里输入类似于 www.baidu.com 这样的地址&#xff0c;那么在浏览器里输入这个地址---> 百度服务器给我们返回这个百度的页面&#xff0c;中间的过程是什么样的呢&#xff1f; 带着这个问题&#xff0c;我们一起来解析一下其中的…

肺癌文献阅读2

第四篇 Neoadjuvant therapy in non-small cell lung cancer IF:6.2 中科院分区:2区 医学WOS 分区:Q1 之前有了解到新辅助治疗与辅助治疗都是在术前为增加疗效而进行的&#xff0c;这篇文章讲到I-III期的NSCLC更倾向于切除&#xff0c;这个时间点可分为早期与晚期。这个III期应…

Qt获取字符串大小

可以用成员函数size、length和count来获取字节数组的大小。除了名字不同&#xff0c;这3个函数是等同的&#xff0c;函数的原型声明如下&#xff1a; int size(); int length(); int count(); 这3个函数返回字节数组中的字节数。Size()函数的用法如下&#xff1a; QByteAr…

代码随想录day2:数组part02(有序数组的平方 ,长度最小的子数组 ,螺旋矩阵II,数组章节总结)

数组part02 一、有序数组的平方 法一&#xff1a;暴力&#xff0c;先把每个元素平方再排序&#xff0c;时间复杂度O(n nlogn) class Solution { public:vector<int> sortedSquares(vector<int>& nums) {for(int i0;i<nums.size();i) nums[i]*nums[i];so…