Golang defer关键字

defer特性

1.关键字defer 用于注册延迟调用

2.这些调用直到return 前才被执行。因此,可以用来做资源清理

3.多个defer语句,按先进后出的方式执行

4.defer语句中的变量,在defer生命时就决定了

defer用途

1.关闭文件句柄

2.锁资源释放

3.数据库连接释放

defer用例

1.多个defer输出顺序
func main() {for i := 0; i < 3; i++ {defer fmt.Println(i) // 1. 这三个 defer 语句会按照 i=0, i=1, i=2 的顺序被推入栈中。}fmt.Println("循环结束") // 2. 循环结束,打印 "循环结束"。if true {defer fmt.Println("条件语句中的 defer") // 3. 这个 defer 语句被推入栈中。}defer fmt.Println("最后的 defer") // 4. 这个 defer 语句被推入栈中。fmt.Println("main 函数执行中") // 5. 打印 "main 函数执行中"。
}//结果
//循环结束
//main 函数执行中
//最后的 defer
//条件语句中的 defer
//2
//1
//0
2.defer遇到循环
//第一个例子
package mainimport "fmt"type Test struct {name string
}func (t *Test) Close() {fmt.Println(t.name, " closed")
}
func main() {ts := []Test{{"a"}, {"b"}, {"c"}}for _, t := range ts {defer t.Close()}
}//结果:c closed 
//c closed
//c closed
//第二个例子
package mainimport "fmt"type Test struct {name string
}func (t *Test) Close() {fmt.Println(t.name, " closed")
}
func Close(t Test) {t.Close()
}
func main() {ts := []Test{{"a"}, {"b"}, {"c"}}for _, t := range ts {defer Close(t)}
}
//结果
//c  closed
//b  closed
//a  closed

第一个例子中,当defer语句被执行时,它都会捕获t当前值的副本,并不是t的地址。由于t是在循环遍历的,每次迭代都会创建t的副本,而不是t的地址。由于t是在循环中逐一遍历的,每次迭代都会创建t的新副本。因此当main函数结束时,defer语句会按照后进先出的顺序执行,但是每个defer调用都会打印循环结束时t的最终副本,即“c”。

第二个例子中的close函数接受一个Test类型的参数,并且调用这个参数的Close方法。由于Close是一个单独的函数,它接收t的副本作为参考。当defer调用Close(t)时,它传递了t的当前值的副本给Close函数。这意味着每个defer调用都捕获了循环中t的当前值的副本。 

3.defer +recover 捕获异常
package mainimport "fmt"func safeDivide(a, b int) (int, error) {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()if b == 0 {return 0, fmt.Errorf("cannot divide by zero")}return a / b, nil
}func main() {result, err := safeDivide(10, 0)if err != nil {fmt.Println("Error:", err)}fmt.Println("Result:", result)
}
4.defer 遇到闭包
package mainimport "fmt"func main() {var whatever [5]struct{}for i := range whatever {defer func() { fmt.Println(i) }()}
}
//结果
//4
//4
//4
//4
//4

这是因为闭包用到的变量i在执行时就已经变成4了,所以输出全是4

注意事项

注意事项

  1. 性能:过度使用 defer 可能会影响性能,因为每个 defer 调用都会创建额外的栈帧。

  2. 控制流defer 语句的执行顺序可能与直觉相反,需要仔细设计以确保逻辑正确。

  3. 错误处理defer 语句中的错误处理代码应该能够处理所有可能的错误情况。

  4. 嵌套使用:嵌套使用 defer 时,确保外层的 defer 能够正确处理内层可能抛出的错误。

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

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

相关文章

基于Java Springboot论坛系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

Vue2教程001:初识Vue

文章目录 1、初识Vue1.1、Vue2前言1.2、创建Vue实例1.3、插值表达式1.4 Vue响应式特性 1、初识Vue 1.1、Vue2前言 Vue是什么&#xff1f; 概念&#xff1a;Vue是一个用于构建用户界面的渐进式框架。 Vue的两种使用方式&#xff1a; Vue核心包开发 场景&#xff1a;局部模块…

113页PPT制造业研发工艺协同及制造一体化

研发工艺协同及制造一体化解决方案是制造业数字化转型的重要组成部分&#xff0c;它涵盖了从产品设计到生产的全过程&#xff0c;旨在提高生产效率、降低成本、提升产品质量&#xff0c;并增强企业的市场竞争力。以下是对该解决方案的详细阐述&#xff1a; 一、方案概述 研发…

红外遥控信号解码

红外遥控信号解码 之前就已经做过红外遥控的解码了&#xff0c;但是一直没有做记录&#xff0c;最近的项目又使用到了红外遥控&#xff0c;索性就把他捡起来记录一下&#xff0c;对于信号的解码&#xff0c;我一般的习惯都是先用逻辑分析仪抓取一下信号波形&#xff0c;然后对…

Spring:纯注解开发模式-Ioc对bean的管理

我们知道&#xff08;请见 注解开发定义bean&#xff09;&#xff0c;可以使用注解来配置bean,但是依然有用到配置文件&#xff0c;在配置文件中对包进行了扫描&#xff0c;Spring在3.0版已经支持纯注解开发 Spring3.0开启了纯注解开发模式&#xff0c;使用Java类替代配置文件…

赛元免费开发板申请

在作者网上冲浪的时候&#xff0c;突然发现了一个国内的良心企业&#xff0c;虽然现在不是很有名&#xff0c;但是他现在是有一个样品申请的活动&#xff0c;他就是国内的Redfine新定义&#xff0c;他申请的板子是用的赛元MCU&#xff0c;作者本着有板子就要申请的原则&#xf…

【编译】多图解释 什么是短语、直接短语、句柄、素短语、可归约串

一、什么是短语二、什么是“直接”短语&#xff1f;三、什么是句柄&#xff1f;四、什么是素短语&#xff1f;五、什么是最左素短语可归约串就是“最左素短语” 首先&#xff0c;这些概念 都是相对于【句型】的&#xff0c;都是相对于【句型】的&#xff0c;都是相对于【句型】…

基础IO2

文章目录 磁盘结构磁盘存储结构磁盘的逻辑结构引入文件系统理解文件系统inode 映射 data blocks文件名与inode的关系dentry树文件描述符与进程之间的关系 深刻理解软硬链接软链接硬链接 动静态库静态库1. 手动制作静态库2.调用静态库(1)安装到系统(2)自己指定查找路径(3)自己创…

RPC-健康检测机制

什么是健康检测&#xff1f; 在真实环境中服务提供方是以一个集群的方式提供服务&#xff0c;这对于服务调用方来说&#xff0c;就是一个接口会有多个服务提供方同时提供服务&#xff0c;调用方在每次发起请求的时候都可以拿到一个可用的连接。 健康检测&#xff0c;能帮助从连…

ZD Soft Screen Recorder:电脑录屏软件

前言 ZD Soft Screen Recorder 是一款屏幕录制软件 安装环境 [名称]&#xff1a;ZD Soft Screen Recorder [版本]&#xff1a;11.7.2 [大小]&#xff1a;6.8MB [语言]&#xff1a;英文 [环境]&#xff1a;pc 链接: 百度网盘 请输入提取码 提取码: ua23 软件界面 1、双击…

某杀软环境下的添加账户

某杀软环境下的添加账户 我们在某个杀软环境下&#xff0c;正常添加账户一般是会被直接拦截的 白&#xff0b;黑 在这个环境下&#xff0c;白&#xff0b;黑是最实用的绕过方式&#xff0c;我们可以通过调用winapi来创建账户&#xff0c;这些代码再存储到dll里面&#xff0c…

《Spring 基础之 IoC 与 DI 入门指南》

一、IoC 与 DI 概念引入 Spring 的 IoC&#xff08;控制反转&#xff09;和 DI&#xff08;依赖注入&#xff09;在 Java 开发中扮演着至关重要的角色&#xff0c;是提升代码质量和可维护性的关键技术。 &#xff08;一&#xff09;IoC 的含义及作用 IoC 全称为 Inversion of…

【C++】set,map,multiset,multimap的介绍和使用

set、map、multiset、multimap set、multiset的介绍和使用1、关联式容器2、键值对3、树形结构的关联式容器4、setset的介绍set的定义set的使用 5、multisetmultiset的介绍multiset的使用 map、multimap的介绍和使用1、map的介绍map的定义insert插入函数map的迭代器find查找函数…

Midjourney基础命令和提示词

1 基础命令 1.1 /imagine prompt 生成图片的核心命令&#xff0c;prompt 后输入描述。 /imagine prompt: A majestic dragon flying over a misty mountain, cinematic lighting, 4K resolution 高级提示 1.1.1 基本参数 图片比例 --ar 图片比例 混乱 Aspect Ratios --…

【代码pycharm】动手学深度学习v2-04 数据操作 + 数据预处理

数据操作 数据预处理 1.数据操作运行结果 2.数据预处理实现运行结果 第四课链接 1.数据操作 import torch # 张量的创建 x1 torch.arange(12) print(1.有12个元素的张量&#xff1a;\n,x1) print(2.张量的形状&#xff1a;\n,x1.shape) print(3.张量中元素的总数&#xff1…

智云-一个抓取web流量的轻量级蜜罐v1.5

智云-一个抓取web流量的轻量级蜜罐v1.5 github地址 https://github.com/xiaoxiaoranxxx/POT-ZHIYUN 新增功能-自定义漏洞信息 可通过正则来添加相关路由以及响应来伪造 nacos的版本响应如下 日流量态势 月流量态势 抓取流量效果

【Android原生问题分析】夸克、抖音划动无响应问题【Android14】

1 问题描述 偶现问题&#xff0c;用户打开夸克、抖音后&#xff0c;在界面上划动无响应&#xff0c;但是没有ANR。回到Launcher后再次打开夸克/抖音&#xff0c;发现App的界面发生了变化&#xff0c;但是仍然是划不动的。 2 log初分析 复现问题附近的log为&#xff1a; 用户…

2024年11月16日 星期六 重新整理Go技术

今日格言 坚持每天进步一点点~ 一个人也可以是一个团队~ 学习全栈开发, 做自己喜欢的产品~~ 简介 大家好, 我是张大鹏, 今天是2024年11月16日星期六, 很高兴在这里给大家分享技术. 今天又是休息的一天, 做了很多的思考, 整理了自己掌握的技术, 比如Java, Python, Golang,…

go-zero(一) 介绍和使用

go-zero 介绍和使用 一、什么是 go-zero&#xff1f; go-zero 是一个基于 Go 语言的微服务框架&#xff0c;提供了高效、简单并易于扩展的 API 设计和开发模式。它主要目的是为开发者提供一种简单的方式来构建和管理云原生应用。 1.go-zero 的核心特性 高性能&#xff1a; g…

VUE+SPRINGBOOT实现邮箱注册、重置密码、登录功能

随着互联网的发展&#xff0c;网站用户的管理、触达、消息通知成为一个网站设计是否合理的重要标志。目前主流互联网公司都支持手机验证码注册、登录。但是手机短信作为服务端网站是需要付出运营商通信成本的&#xff0c;而邮箱的注册、登录、重置密码&#xff0c;无疑成为了这…