go语言中defer用法详解

news/2024/11/1 19:27:36/

defer 是 Go 语言中的一个关键字,用于延迟执行某个函数或语句,直到包含它的函数返回时才执行。defer 语句在函数执行结束后(无论是正常返回还是由于 panic 返回)都将执行。

defer 的基本用法

  1. 延迟执行: 当你在一个函数内调用 defer 语句,后面的语句将被推迟到该函数执行结束时执行。

    package mainimport "fmt"func main() {defer fmt.Println("这是最后执行的语句")fmt.Println("这是先执行的语句")
    }
    

    输出:

    这是先执行的语句
    这是最后执行的语句
    
  2. 多个 defer 语句: 如果一个函数中有多个 defer 语句,它们会按照后进先出(LIFO)的顺序执行。

    package mainimport "fmt"func main() {defer fmt.Println("第一个 defer")defer fmt.Println("第二个 defer")defer fmt.Println("第三个 defer")fmt.Println("主函数中的代码")
    }
    

    输出:

    主函数中的代码
    第三个 defer
    第二个 defer
    第一个 defer
    

  3. 传递参数: 在 defer 语句中传递参数时,参数在 defer 被调用时就会被评估,而不是在执行时。

    package mainimport "fmt"func main() {for i := 0; i < 3; i++ {defer fmt.Println(i) // 这里的 i 会被延迟执行}
    }
    

    输出:

    2
    1
    0
    

    如果在 defer 语句中直接使用 i 的值而不是它的引用,结果会是这样的。

defer 的常见用途

  1. 资源清理defer 常用于释放资源,如关闭文件、数据库连接等。这样可以确保即使在函数中发生错误时,资源仍然能被正确释放。

    package mainimport ("fmt""os"
    )func main() {file, err := os.Open("example.txt")if err != nil {fmt.Println("打开文件错误:", err)return}defer file.Close() // 确保文件在函数结束时被关闭// 处理文件...
    }
    

  2. 错误处理: 结合 recover 使用,可以处理 panic 并进行错误处理。

    package mainimport "fmt"func recoverFromPanic() {defer func() {if r := recover(); r != nil {fmt.Println("捕获到 panic:", r)}}()panic("发生了错误") // 触发 panic
    }func main() {recoverFromPanic()fmt.Println("程序继续运行")
    }
    

  3. 函数执行时间测量: 可以使用 defer 来测量函数执行时间。

    package mainimport ("fmt""time"
    )func main() {start := time.Now()defer func() {fmt.Println("函数执行时间:", time.Since(start))}()// 模拟耗时操作time.Sleep(2 * time.Second)
    }
    

总结

defer 是 Go 语言中一个强大且灵活的工具,适用于资源管理、错误处理和其他需要在函数返回时执


http://www.ppmy.cn/news/1543669.html

相关文章

计算机网络(Ⅴ)网络核心

电路交换 为源主机分配了独享的线路。有资源浪费是缺点。 优点是保障了性能&#xff0c;但是资源共享的能力较差&#xff08;计算机的通讯不是持续的&#xff0c;具有突发性&#xff0c;不适用于电路交换&#xff09; 频分&#xff08;FDM&#xff09;&#xff1a;交换节点与交…

2024不可不会的StableDiffusion

需要Stable Diffusion整合包可以扫描下方,免费获取 01 引言 这是我在学习StableDiffusion (稳定扩散模型 简称SD)的第一篇入门文章&#xff0c;主要用于介绍稳定扩散模型和该领域的其他研究。在本文中&#xff0c;我想简要介绍一下如何使用Diffusers 扩散库&#xff0c;来创建…

Docker 命令指南:详细概述与示例应用

Docker 命令指南&#xff1a;详细概述与示例应用 Docker 是一个强大的容器化平台&#xff0c;为容器的创建、管理和运行提供了广泛的支持。通过 Docker 的命令行工具&#xff0c;用户可以从基本的镜像管理、容器操作到复杂的网络和数据存储管理执行各种任务。本节将详细介绍 D…

大厂物联网(IoT)高频面试题及参考答案

目录 解释物联网 (IoT) 的基本概念 物联网的主要组成部分有哪些? 描述物联网的基本架构。 IoT 与传统网络有什么区别? 物联网中常用的传感器类型有哪些? 描述物联网的三个主要层次。 简述物联网中数据安全的重要性 描述物联网安全的主要威胁 解释端到端加密在 IoT 中…

两个有序链表序列的交集

两个有序链表序列的交集 一、问题描述 给定两个有序链表&#xff0c;要求找出这两个链表的交集元素&#xff0c;并以有序链表的形式返回。 二、思路 双指针法&#xff1a;使用两个指针分别指向两个链表的当前节点。比较元素&#xff1a; 如果两个指针指向的元素相等&#x…

「C/C++」C++设计模式 之 Pimpl模式

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

Threejs渲染3D字体介绍

概述 本文主要介绍如何通过 Three.js 生成 3D 文本。 效果展示 代码分析 核心代码部分就是通过 Three.js 中的 FontLoader 和 TextGeometry 来加载字体并创建 3D 文本。 核心代码如下: const loader = new FontLoader();loader.load(textFamily.value, function (font) {…

一套CRM多少钱?

在企业的客户关系管理中&#xff0c;CRM 系统起着至关重要的作用。随着市场上 CRM 系统的种类繁多&#xff0c;其价格也成为企业关注的焦点。那么&#xff0c;一套 CRM 系统究竟需要多少钱呢&#xff1f;这受到多种因素的影响&#xff0c;今天我就来和大家好好聊聊这个问题。大…