go的defer机制

news2024/11/23 18:42:20

defer的底层机制

为栈操作,栈是一个先进后出的数据结构

func main() {
    fmt.Println("reciprocal")

    for i := 0; i < 10; i++ {
        defer fmt.Println(i)
    }
}

运行结果
reciprocal
9
8
7
6
5
4
3
2
1
0

defer拷贝机制

以下已经发生压栈发生值拷贝数据不再会发生变化

func test() int {
	var i = 1
	defer func(i int) {
		fmt.Println("数据压栈已压栈数据不会在发生变化", i)
	}(i)
	i++
	return i
}

运行结果

数据压栈已压栈数据不会在发生变化 1

函数返回值 2

deferreturn的返回时机(执行顺序)

根据defer内的变量为匿名函数,还是命名函数。函数的返回数据会有差距

1. 计算并赋值返回值

• 对于匿名返回值的函数,return 语句先会计算并生成返回值,并将其赋值给一个临时变量。

• 对于命名返回值的函数,return 语句会将结果赋值给命名的返回变量,这个变量在函数开始时就已经声明。

2. 执行 defer 语句

• defer 语句中的函数在 return 语句执行后被调用,但它们的执行顺序是后进先出 (Last In First Out, LIFO) 的。

• defer 函数可以操作命名返回值,从而可能修改最终的返回值。

3. 返回结果

• 在 defer 函数执行完后,返回最终的结果。

实践匿名函数

func main() {
	fmt.Println(Anonymous())
}

func Anonymous() int {
	var i int
	defer func() {
		i++
		fmt.Println("defer2 value is ", i)
	}()

	defer func() {
		i++
		fmt.Println("defer1 in value is ", i)
	}()

	return i
}

结果

defer1 in value is  1

defer2 value is  2

0

执行过程

        1. 函数执行到 return i 时,i 的值是 0。

        2. 执行 defer 语句,先执行 defer1,然后执行 defer2,此时 i 变为 2,但 return 的返回值已                固定为 0。

        3. 最终返回值为 0。

实践命名返回值的函数

func main() {
	fmt.Println(HasName())
}

func HasName() (j int) {
	defer func() {
		j++
		fmt.Println("defer2 in value", j)
	}()

	defer func() {
		j++
		fmt.Println("defer1 in value", j)
	}()

	return j
}

结果
defer1 in value 1
defer2 in value 2
2

执行过程

1. 函数执行到 return j 时,j 的初始值为 0。

2. 执行 defer 语句,先执行 defer1,j 变为 1,再执行 defer2,j 变为 2。

3. 最终返回值为 2,因为 defer 修改了命名返回值 j。

总结

匿名返回值函数:return 语句计算出返回值并存储在临时变量中,随后执行 defer 函数,但 defer 对返回值的修改不会影响最终返回值。

命名返回值函数:return 语句返回命名的返回变量,defer 函数能够修改这个变量,因此它会影响最终返回值。

defer 执行顺序的规则

1. defer 的参数在 defer 语句处计算。

2. defer 函数在函数返回时按照后进先出的顺序执行。

3. defer 函数可以读写返回函数的命名返回值。

defer 的使用场景:

1. 关闭资源

在处理文件、数据库连接、网络连接等需要关闭的资源时,defer 确保资源在使用完毕后被正确关闭,即使中间发生了错误。

2. 解锁资源

当使用 sync.Mutex 等锁机制时,defer 确保锁在临界区代码执行完毕后被解锁,从而避免死锁情况的发生。defer 释放分布式锁,防止死锁

3.记录日志或执行收尾工作

defer 可以用来记录函数的退出状态,或者在函数结束前执行一些收尾操作,例如日志记录或计时。

4. 处理错误和恢复(recover)

在可能会引发 panic 的代码中,defer 可以用来捕获和恢复错误,防止程序崩溃。

5. 清理临时状态

在函数内创建了一些临时状态或变量,需要在函数结束时清理时,defer 可以确保这些清理操作被执行。

引用

详解defer实现机制(附上三道面试题,我不信你们都能做对)

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

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

相关文章

【Python机器学习系列】一文教你绘制多分类任务的ROC曲线-宏平均ROC曲线(案例+源码)

这是我的第345篇原创文章。 一、引言 ROC曲线是用于评估二分类模型性能的工具&#xff0c;它展示了模型在不同阈值下的真阳性率与假阳性率之间的关系&#xff0c;但是标准的ROC并不能运用于多分类任务种&#xff0c;于是扩展出了宏平均ROC曲线。 宏平均ROC曲线是多分类问题中…

工业控制常用“对象“数据类型汇总(数据结构篇)

合理巧妙的数据结构会大大简化项目的编程工作量,所以任何项目前期第一步应该是设计巧妙的数据结构、封装对象属性。这样会使我们的编程快捷和高效。这篇博客作为数据类型汇总,会不间断更新。 1、普通电机轴对象 2、普通电机轴对象(详细结构变量) TYPE "udtMotorAxis&q…

机器学习的入门笔记(第十五周)

本周观看了B站up主霹雳吧啦Wz的图像处理的课程&#xff0c; 课程链接&#xff1a;霹雳吧啦Wz的个人空间-霹雳吧啦Wz个人主页-哔哩哔哩视频 下面是本周的所看的课程总结。 利用GoogLeNet进行图像分类 GoogLeNet是由 Google 提出的卷积神经网络架构&#xff0c;于 2014 年在 …

没有用的小技巧之---接入网线,有内网没有外网,但是可以登录微信

打开控制面板&#xff0c;找到网络和Internet 选择Internet选项 点击连接&#xff0c;选择局域网设置 取消勾选代理服务器

JetBrains CLion 2024.2 (macOS, Linux, Windows) - C 和 C++ 跨平台 IDE

JetBrains CLion 2024.2 (macOS, Linux, Windows) - C 和 C 跨平台 IDE JetBrains 跨平台开发者工具 请访问原文链接&#xff1a;https://sysin.org/blog/jetbrains-clion/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Jet…

实战勤务指挥系统解决方案

4. 总体设计方案 方案围绕业务需求、接口需求和安全需求进行设计&#xff0c;包括语音集成、视频图像集成和第三方系统集成&#xff0c;以实现多系统联动和资源共享。 5. 系统特色 系统特色包括高度融合的指挥应用模式、简化的指挥流程、高效的管理机制&#xff0c;以及基于…

《Windows PE》2.1 初识PE文件

Windows PE文件&#xff08;Portable Executable file&#xff09;是一种可执行文件格式&#xff0c;用于Windows操作系统中的可执行程序、动态链接库&#xff08;DLL&#xff09;和驱动程序等。它是一种规范化的文件格式&#xff0c;定义了文件的结构和组织方式&#xff0c;以…

go设计模式———抽象工厂模式

抽象工厂模式概念 抽象工厂模式是一种设计模式&#xff0c;它允许创建一系列相关的对象&#xff0c;而无需指定具体的类。具体来说&#xff0c;抽象工厂定义了用于创建不同产品的接口&#xff0c;但实际的创建工作则由具体的工厂类完成。每个具体工厂负责创建一组相关的产品&am…

谷歌账号停用后申诉了,也收到了谷歌的邮件,如何判断谷歌申诉是否成功,成功了怎么办?被拒绝谷歌账号就废了吗?

似乎是谷歌分工机制的更新&#xff0c;最近谷歌账号“被停用”的情况貌似多了起来&#xff0c;许多朋友在谷歌账号提示活动异常&#xff0c;要输入手机号码恢复账号的时候&#xff0c;无论是否立刻恢复&#xff0c;很快好像就迎来了“您的账号已停用”的结果。或者有一些朋友许…

多元统计分析——基于R语言的单车使用情况可视化分析

注&#xff1a;基于R语言的单车使用情况可视化分析为实验记录&#xff0c;存在不足&#xff0c;自行改进。 一、提出问题&#xff08;要解决或分析的问题&#xff09; 1 、用户对共享单车的使用习惯&#xff0c;环境对共享单车运营带来的影响&#xff1f; 2 、共享单车的租赁…

【北京仁爱堂】痉挛性斜颈的健康指导

痉挛性斜颈是一种肌肉紧张异常症&#xff0c;仅限于颈部肌肉的肌张力障碍。当患者患有痉挛性斜颈&#xff0c;会表现为颈部肌肉间歇性或持续不规则的收缩&#xff0c;因此患者的头颈部会出现扭曲、歪斜、姿势异常等症状&#xff0c;多发于30-40岁左右中年人 一、 痉挛性斜颈的5…

mac和windows上安装nvm管理node版本

NVM 是 node version manager 的缩写&#xff0c;它是一个用来管理电脑上 node 版本的命令行工具&#xff0c;在日常前端开发中是一个跟 node 一样会经常用到的工具&#xff0c;可以很方便的让我们快速切换不同的node版本。 mac 上安装 nvm 1、下载安装 nvm 下载安装可以直…

【机器学习】逻辑回归原理(极大似然估计,逻辑函数Sigmod函数模型详解!!!)

目录 &#x1f354; 逻辑回归应用场景 &#x1f354; 极大似然估计 2.1 为什么要有极大似然估计&#xff1f; 2.2 极大似然估计步骤 2.3 极大似然估计的例子 &#x1f354; Sigmod函数模型 3.1 逻辑斯特函数的由来 3.2 Sigmod函数绘图 3.3 进一步探究-加入线性回归 3…

【爬虫】 使用AI编写B站爬虫代码

记录一次&#xff0c;自己不写一行代码&#xff0c;所有的代码全由AI编写的过程。 本次使用的AI工具为&#xff1a;Claude 其他AI工具同理。 首先&#xff0c;观察哔哩哔哩网页的结构&#xff0c;定位到了包含视频信息的关键元素。右键检查或打开F12&#xff0c;找到最左侧的这…

2024前端面试题-js篇

1.js有哪些数据类型 基础数据类型&#xff1a;string,number,boolean&#xff0c;null&#xff0c;undefined&#xff0c;bigInt&#xff0c;symbol 引用数据类型&#xff1a;Object 2.js检测数据类型的方式 typeof&#xff1a;其中数组、对象、null都会被判断为object&…

基于WebSocket打造的一款SSH客户端

引用&#xff1a;Java打造一款SSH客户端&#xff0c;而且已开源_java ssh客户端-CSDN博客 由于原作者是放在Github上&#xff0c;不方便下载&#xff0c;所以下载下来&#xff0c;转存到码云上&#xff0c;地址&#xff1a;https://gitee.com/lfw1024/web-ssh 为了满足一些小白…

计算机毕业设计选题推荐-股票数据可视化分析与预测-Python爬虫

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Windows10拿到shell后远程登录

一、准备工作 kali机&#xff1a;192.168.19.130 win10&#xff1a;192.168.19.133 主机&#xff1a;192.168.1.73&#xff08;自己操作可以在kali上&#xff0c;我这是因为反弹的shell在主机上&#xff09; 二、开启远程登录 1.win10上关闭实时保护&#xff0c;并且运行了…

[C++] C++11详解 (一)

标题&#xff1a;[C] C11详解 (一) 水墨不写bug 目录 前言 一、列表初始化 二、STL的初始化列表&#xff08;initializer_list —— Cplusplus.com&#xff09; 三、声明方式&#xff08;auto、decltype、nullptr&#xff09; 1.auto ​编辑 2.decltype 正文开始&#x…

Spark环境搭建-Local

目录 Local下的角色分布&#xff1a; Anaconda On Linux 安装 (单台服务器) 1.下载安装 2.国内源 下载Spark安装包 1.下载 2.解压 3.环境变量 测试 监控 Local下的角色分布&#xff1a; 资源管理&#xff1a; Master&#xff1a;Local进程本身 Worker&#xff1a;L…