阐述一下Golang中defer的原理

news2024/11/25 16:48:14

基本用法

在Go语言中,defer关键字用于在函数返回前执行一段代码或调用一个清理函数。这对于处理文件关闭、解锁或者返回一些资源到资源池等操作非常有用。

其基本用法如下所示:

package main

import "fmt"

func main() {
	example()
}

func example() {
	defer fmt.Println("world")
	fmt.Println("hello")
}

defer fmt.Println("world")语句会在函数example返回之前执行,所以输出的结果是:

在这里插入图片描述

执行顺序

当我们在一个函数内部调用defer关键字,Go实际上会把它后面的函数(通常是一个匿名函数或者清理函数)压入一个栈中。当外部函数准备返回的时候,Go会按照先进先出的(LIFO)的顺序调用并执行这个栈中的所有函数。

比如,如下示例:

package main

import "fmt"

func main() {
	example()
}

func example() {
	defer fmt.Println("first")
	defer fmt.Println("second")
	defer fmt.Println("third")
	fmt.Println("function body")
}

其输出结果为:在这里插入图片描述

参数计算时机

需要注意的是,defer语句的参数会在defer语句处就计算好,而不是在外部函数返回时才计算。比如如下例子

package main

import "fmt"

func main() {
	example()
}

func example() {
	i := 0
	defer fmt.Println(i) 
	i++
	fmt.Println(i)
}
/*
1
0
*/

实际应用举例

关闭文件
package main

import (
	"fmt"
	"io/ioutil"
	"os"
)

func readFile(fileName string) (string, error) {
	file, err := os.Open(fileName)
	if err != nil {
		return "", err
	}
	defer file.Close() // 确保文件在函数返回前被关闭

	content, err := ioutil.ReadAll(file)
	if err != nil {
		return "", err
	}
	return string(content), nil
}

func main() {
	content, err := readFile("example.txt")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("File content:", content)
}
解锁互斥锁
package main

import (
	"fmt"
	"sync"
)

var mtx sync.Mutex
var cnt int

const N int = 10

func increment() {
	mtx.Lock()
	defer mtx.Unlock()
	cnt++
}

func main() {
	var wg sync.WaitGroup

	for i := 0; i < N; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			increment()
		}()
	}

	wg.Wait()
	fmt.Println("Final count: ", cnt)
}

释放网络连接
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func fetchURL(url string) (string, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close() // 确保连接在函数返回前被关闭

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(body), nil
}

func main() {
	content, err := fetchURL("http://baidu.com")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("URL content:", content)
}

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB

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

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

相关文章

解决uniapp h5 本地代理实现跨域访问及如何配置开发环境

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 如何解决uniapp H5本地代理实现跨域访问&#xff1f; 1.第一种解决方法&#xff1a; 直接创建一个vue.config.js文件&#xff0c;并在里面配置devServer&#xff0c;直接上…

Transformer预测 | 基于Transformer的风电功率多变量时间序列预测(Matlab)

文章目录 预测效果文章概述模型描述程序设计参考资料预测效果 文章概述 Transformer预测 | 基于Transformer的风电功率多变量时间序列预测(Matlab) Transformer 模型本质上都是预训练语言模型,大都采用自监督学习 (Self-supervised learning) 的方式在大量生语料上进行训练,…

国产基于Vue+Echarts 免费开源 AIoT 物联网可视化Web组态大屏解决方案

项目源码&#xff0c;文末联系小编 01 DataRoom可视化大屏开发工具 DataRoom是一款基于SpringBoot、MyBatisPlus、ElementUI、G2Plot、Echarts等技术栈的大屏设计器&#xff0c;前后端一体化架构&#xff0c;拥有几十种炫酷图表。具备大屏分组管理、大屏设计、大屏预览能力&…

Marin说PCB之如何在CST仿真软件中添加三端子的电容模型?

上期文章小编我给诸位道友们分享了Murata家的三端子电容的一些特性&#xff0c;这期文章接着上回把三端子电容模型如何在CST软件中搭建给大家分享一下&#xff0c;小编我辛辛苦苦兢兢业业的给各位帖子们免费分享我的一些设计心得&#xff0c;这些按照小编我华山派门派的要求都是…

chrome浏览器 network 显示感叹号(chrome network thinttling is enabled)

chrome浏览器上network出现一个黄色感叹号&#xff0c;鼠标移上去提示chrome network thinttling is enabled&#xff0c;这是因为开启了节流模式&#xff0c;直接把网络模式改为no throttling&#xff08;有的浏览器为online&#xff09;就可以了。 ##Tips&#xff1a; 1、n…

JavaScript的学习之强制类型转换

目录 一、什么是强制类型转换 二、其他类型转化为String类型 方式一&#xff1a;调用被转化数据类型的toString()方法 方式二&#xff1a;调用String函数&#xff0c;并将我们要转换的数据添加进去为参数 三、其他类型转化为Number类型 方式一&#xff1a;使用Number()函数…

云渲染与传统渲染器的较量与融合

随着云计算技术的突破性进展&#xff0c;云渲染技术应运而生&#xff0c;为传统渲染器带来了前所未有的挑战与机遇。云渲染&#xff0c;以其在计算资源、可扩展性、协作便利性等方面的显著优势&#xff0c;正在重新定义渲染行业的标准。云渲染与传统渲染器之间的核心差异&#…

【机器学习】Lasso回归:稀疏建模与特征选择的艺术

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Lasso回归&#xff1a;稀疏建模与特征选择的艺术引言一、Lasso回归简介1.1 基本…

人脸识别——可解释的人脸识别(XFR)人脸识别模型是根据什么来识别个人的

可解释性人脸识别&#xff08;XFR&#xff09;&#xff1f; 人脸识别有一个任务叫1:N&#xff08;识别&#xff09;。这个任务将一个人的照片与N张注册照片进行比较&#xff0c;找出相似度最高的人。 这项任务用于刑事调查和出入境点。在犯罪调查中&#xff0c;任务从监控摄像…

【文心智能体大赛】迎接属于你的休闲娱乐导师!

迎接属于你的休闲娱乐导师&#xff01; 前言创建智能体发布智能体最后结语 前言 文心智能体平台AgentBuilder 是百度推出的基于文心大模型的智能体&#xff08;Agent&#xff09;平台&#xff0c;支持广大开发者根据自身行业领域、应用场景&#xff0c;选取不同类型的开发方式&…

02 Shell 编程之条件语句

目录 2.1 条件测试语句 2.1.1 文件测试 2.1.2 整数值比较 2.1.3 字符串比较 2.1.4 逻辑测试 2.2 if 条件语句 2.2.1 if 语句的结构 1. 单分支if 语句 2. 双分支if 语句 3. 多分支if 语句 2.2.2 if 语句应用示例 1. 单分支if 语句应用 2. 双分支if 语句应用 3. 多分支if 语句应…

【Linux】rouyiVue 项目部署全过程(含MySQL,Nginx等中间件部署)

查看nginx 进程命令 ps aux | grep server_name 1. 安装MySQL 1.1 下载压缩包 官网下载 1.2 解压 上传并解压好放在指定位置 创建soft文件夹 mkdir /soft上传文件&#xff0c;在该目录下再创建一个mysql文件夹&#xff0c;将安装包解压到新文件夹中 mkdir /soft/mysql-…

智能汽车 UI 风格独具魅力

智能汽车 UI 风格独具魅力

windows7虚拟机安装vmtools方法

kb4474419补丁 # 1.下载补丁 Microsoft Update Catalog # 2. 传输文件至windows7虚拟机 方法很多&#xff0c;如certutil、 powershell 、bitsadmin 、 smb 、 rdp 等均能进行文件传输 这里使用vmware共享文件夹进行传输 # 设置共享文件夹 在物理机文件夹放入文件&#xff0…

IDEA 学习之 启动“卡死”

目录 1. 断点问题2. IDEA 版本问题 1. 断点问题 部分断点涉及应用启动&#xff0c;会导致启动“卡死” 2. IDEA 版本问题 部分 IDEA 版本存在启动问题&#xff0c;本人之前遇到过&#xff08;别人启动三分钟&#xff0c;我启动半个小时&#xff09;。更换别的版本&#xff…

playwright vscode 插件源码解析

Playwright vscode插件主要功能 Playwright是微软开发的一款主要用于UI自动化测试的工具&#xff0c;在vscode中上安装playwright vscode插件&#xff0c;可以运行&#xff0c;录制UI自动化测试。 playwright vscode插件主要包括两块功能&#xff0c;功能一是在Test Explorer中…

Spring事务介绍、Spring集成MyBatis

目录 1.Spring的事务1.1 什么是事务&#xff1f;1.2 事务的特性&#xff08;ACID&#xff09;1.3 Spring 事务实现方式有哪些&#xff1f;1.4 Spring事务管理接口介绍1.4.1 PlatformTransactionManager:事务管理接口1.4.2 TransactionDefinition:事务属性事务管理器接口1.4.3 T…

vue3+Vite项目中引入Element plus组件库及基本使用步骤

一、Element Plus组件库介绍 Element Plus组件库饿了么团队为Vue3发布的组件库&#xff0c;它含有丰富的样式&#xff0c;该组件的官网&#xff1a;element-plus。 二、Element Plus组件安装 (1)通过vscode打开创建的vue项目&#xff0c;本文的项目名称为“shop-admin”,打开项…

mysql设置密码复杂度策略,登录失败次数限制

在配置文件中加入如下配置&#xff0c;重启mysql服务 [mysqld] #密码复杂度插件 plugin-load-addvalidate_password.so validate-passwordFORCE_PLUS_PERMANENT validate_password_policy2 # 0简单 1普通 2困难 validate_password_length9 # 密码长度限制 #登录失败次数、时间…

stable diffusion 模型融合

【抛砖引玉】GhostMixV2.0的制作过程及关于Checkpoint模型融合的一点经验 - 知乎大家好,我是Ghost_Shell,也是GhostMix的作者。本来想写一篇文章整体介绍一下模型,一些你们可能没察觉到,但我非常固执的理念,也算是模型的特性。结果发现写太长了,就分开两部分,第一部分是…