【Go】探索Go语言中的关于defer的应用


冬来的秋去
像记忆裂痕
又再变更空枕触遗憾
半梦半醒侵沾眼晴的泪痕
每晚夜深妄想真情接近
绻梦绻恋一宵雨侵悲不禁
永远最相衬
但愿梦里是永恒
——《永远之后-黄艺明》


在Go语言中,defer语句是一个非常强大且常用的特性,它允许我们在函数结束时执行一些清理操作或者确保某些代码在函数执行结束前被执行。本文将探讨defer语句的基本概念、使用案例以及在不同场景下的应用,包括读写文件和Go并发编程中的使用。

defer栈的概念

在了解defer语句的使用之前,首先需要了解defer栈的概念。在Go语言中,当一个函数中包含多个defer语句时,这些defer语句将按照后进先出(LIFO)的顺序执行。这意味着最后一个被defer的语句将会最先执行,而最先被defer的语句将会最后执行。

使用案例

读写文件

func readFile(filename string) ([]byte, error) {file, err := os.Open(filename)if err != nil {return nil, err}defer file.Close() // 确保在函数返回前关闭文件data, err := ioutil.ReadAll(file)if err != nil {return nil, err}return data, nil
}

在这个例子中,defer语句确保了在函数返回前关闭了打开的文件,无论读取文件是否成功。
Go并发

func parallelTask() {var wg sync.WaitGroupdefer wg.Wait() // 等待所有任务完成for i := 0; i < 10; i++ {wg.Add(1) // 将WaitGroup的计数器加1,表示有一个新的任务需要等待go func() {defer wg.Done() // 当任务完成时,将WaitGroup的计数器减1// 执行并发任务}()}
}

当在Go中执行并发任务时,有时我们需要等待所有的并发任务完成后再继续执行后续的代码。这种情况下,我们可以使用sync.WaitGroup来实现并发任务的等待。sync.WaitGroup提供了一种机制,可以等待一组goroutine执行完毕。
sync.WaitGroup是一个计数信号量,用于等待一组goroutine的结束。在函数开头,我们创建了一个WaitGroup实例wg。

使用wg.Add(1)WaitGroup的计数器加1,这表示有一个新的任务需要等待。在这个例子中,我们有10个任务,所以调用了10次wg.Add(1)

在每个goroutine的结尾,我们使用defer wg.Done()WaitGroup的计数器减1,表示一个任务已经完成。这样可以确保即使在goroutine执行过程中发生了错误,也能够保证计数器会被减少。

最后,通过defer wg.Wait()语句,我们将等待所有的任务完成。wg.Wait()会一直阻塞当前goroutine,直到WaitGroup的计数器减为0,即所有的任务都已经完成。此时,parallelTask()函数会继续执行后续的代码。
通过合理地使用sync.WaitGroup,我们可以在并发任务中实现等待,确保所有的任务都已经完成后再执行后续的操作,这对于处理并发任务的场景非常有用。

结语

通过本文的介绍,我们深入了解了defer语句在Go语言中的概念和应用。无论是文件操作还是并发编程,defer语句都是一种强大的工具,可以确保资源的及时释放和代码的清晰性。在编写Go代码时,合理地使用defer语句可以提高代码的可读性和可维护性,同时减少资源泄漏的可能性。

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

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

相关文章

【输入】NTC热敏电阻B值计算程序

两个主要的步骤&#xff1a; 设计分压器电路来测量NTC&#xff08;负温度系数热敏电阻&#xff09;的阻值。编写C语言函数来使用测量的阻值和NTC参数计算温度。 首先&#xff0c;让我们设计分压器电路。 分压器电路设计 您需要一个已知阻值的参考电阻&#xff0c;通常推荐与…

关于遗传力常见的误解

大家好&#xff0c;我是邓飞&#xff0c;今天看了一篇非常好的文章&#xff0c;介绍了遗传力相关概念和计算方法&#xff0c;里面提到了常见的误解&#xff0c;这里汇总一下。 文献链接&#xff1a;https://excellenceinbreeding.org/sites/default/files/manual/EiB-M2_Herit…

STM32CubeMX学习笔记20——SD卡FATFS文件系统

1. FATFS文件系统简介 文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构&#xff08;即在存储设备上组织文件的方法&#xff09;。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统&#xff0c;简称文件系统&#xff1b;不带文件系统的SD卡仅能…

C++初阶:类和对象(四)运算符重载与日期类Date的实现

在本节&#xff0c;我将通过实现日期类Date的实现来进一步阐释运算符重载的内容。 目录 一、Date.h 二、Date.cpp 三、test.cpp 一、Date.h #include<iostream> #include<cassert> using namespace std; class Date { public:// 获取某年某月的天数// 其为内联…

seo js转码工具

js转码工具作用 用于把js加密 如果不想让别人看到自己的js 代码就可以使用这个方法 js工具网址 https://tool.chinaz.com/js.aspx 效果

【大厂AI课学习笔记NO.74】人工智能产业技术架构

包括基础层、技术层和应用层。 人工智能的产业技术架构是一个多层次、多维度的复杂系统&#xff0c;它涵盖了从基础硬件和软件设施到高级算法和应用技术的全过程。这个架构通常可以分为三个主要层次&#xff1a;基础层、技术层和应用层。下面我将详细论述这三个层次及其细分内…

基于Yolo5模型的动态口罩佩戴识别安卓Android程序设计

禁止完全抄袭&#xff0c;引用注明出处。 下载地址 前排提醒&#xff1a;文件还没过CSDN审核&#xff0c;GitHub也没上传完毕&#xff0c;目前只有模型的.pt文件可以下载。我会尽快更新。 所使用.ptl文件 基于Yolo5的动态口罩佩戴识别模型的pt文件资源-CSDN文库 项目完整文…

ES6基础4

Set 基本用法 ES6提供了新的数据结构Set。它类似于数组&#xff0c;但是成员的值都是唯一的&#xff0c;没有重复的值。Set本身是一个构造函数&#xff0c;用来生成Set数据结构。 // 例一 var set new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4]// 例二 var items new …

升级ChatGPT4.0失败的解决方案

ChatGPT 4.0科普 ChatGPT 4.0是一款具有多项出众功能的新一代AI语言模型。以下是关于ChatGPT 4.0的一些关键特点和科普内容&#xff1a; 多模态&#xff1a;ChatGPT 4.0具备处理不同类型输入和输出的能力。这意味着它不仅可以接收文字信息&#xff0c;还能处理图片、视频等多…

CNN中常见的池化操作有哪些,作用是什么?

CNN中常见的池化操作有哪些&#xff0c;作用是什么&#xff1f; CNN中常见的池化操作只要是两种&#xff0c;平均值池化和最大值池化最大值池化常用于分类任务&#xff0c;是指在输入数据的局部区域内取最大值作为输出。最大池化的作用是降低特征图的尺寸&#xff0c;减少参数…

C++17中auto作为非类型模板参数

非类型模板参数是具有固定类型的模板参数&#xff0c;用作作为模板参数传入的constexpr值的占位符。非类型模板参数可以是以下类型&#xff1a; (1).整型&#xff1b; (2).枚举类型&#xff1b; (3).std::nullptr_t&#xff1b; (4).指向对象的指针或引…

vscode中解决驱动编写的时候static int __init chrdev_init()报错的问题

目录 错误出错原因解决方法 错误 在入口函数上&#xff0c;出现 expected a ; 这样的提示 出错原因 缺少了 __KERNEL __ 宏定义 解决方法 补上__KERNEL__宏定义 具体做法&#xff1a;在vscode中按下ctrlshiftp &#xff0c;输入&#xff1a;C/C:Edit Configurations&#xff0…

AcWing 4956. 冶炼金属

对于这个题&#xff0c;V越大&#xff0c;除出来的数就越小&#xff0c;V越小&#xff0c;除出来的数就越大&#xff0c;当我们找一个最大和最小值的时候&#xff0c;就可以通过这个性质进行二分来求解。 可以通过求满足 [ A V ] [\frac{A}{V}] [VA​] 小于等于 B B B的最小的…

手把手教使用静默 搭建Oracle 19c 一主一备ADG集群

一、环境搭建 主机IPora19192.168.134.239ora19std192.168.134.240 1.配置yum源 1.配置网络yum源 1.删除redhat7.0系统自带的yum软件包&#xff1b; rpm -qa|grep yum >oldyum.pkg 备份原信息rpm -qa|grep yum|xargs rpm -e --nodeps 不检查依赖&#xff0c;直接删除…

EE5437-IOT(Lecture 07-Control Interface System)

Review&#xff1a; introduce the micro input device system&#xff08;MIDS&#xff09; • The calibration and testing has been covered • The introduction to filters with the example called Butterworth filter and the maths have been also demonstrated. …

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:CalendarPicker)

日历选择器组件&#xff0c;提供下拉日历弹窗&#xff0c;可以让用户选择日期。 说明&#xff1a; 该组件从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 CalendarPicker(options?: CalendarOptions) …

跨境账号养号怎么做?Facebook、亚马逊运营必看

之前我们讨论过很多关于代理器的问题。它们的工作原理是什么?在不同的软件中要使用那些代理服务器?这些代理服务器之间的区别是什么?什么是反检测浏览器等等。 除了这些问题&#xff0c;相信很多人也会关心在使用不同平台的时代理器的选择问题。比如&#xff0c;为什么最好…

Mybatis操作sql报错ibatis.binding.BindingException: Parameter ‘empId‘ not found.

你们好&#xff0c;我是金金金。 场景 在使用Mybatis操作sql语句过程当中&#xff0c;更新操作&#xff0c;报错信息如下&#xff1a;Caused by: org.apache.ibatis.binding.BindingException: Parameter ‘empId’ not found. Available parameters are [arg1, arg0, param1, …

m序列生成器

function [m] mserial_generator(tap_set) % m序列产生器 % 输出为m序列&#xff0c;未进行极性变换。 L 2^(length(tap_set)-1)-1; x [zeros(1,(length(tap_set)-2)) 1]; for i 1:1:Lm(i)x(end);for j 1:1:length(tap_set)-1sum_vector(j)tap_set(j1)*x(j);endsum_x mod…

聊聊python中面向对象编程思想

面向对象编程思想 1、什么是面向过程 传统的面向过程的编程思想总结起来就八个字——自顶向下&#xff0c;逐步细化&#xff01; → 将要实现的功能描述为一个从开始到结束按部就班的连续的“步骤” → 依次逐步完成这些步骤&#xff0c;如果某一个步骤的难度较大&#xff…