目录

文章目录

  • 目录
  • defer 关键字
  • defer 的用途之一:释放资源
  • defer 的用途之二:执行 recover(恢复)
  • defer 特性
    • 多个 defer 的执行顺序
    • 被 deferred 函数的参数在 defer 时确定
    • 被 defer 的函数可以读取和修改带名称的返回值

defer 关键字

go 用 defer(推迟)关键字来延迟执行指定的函数,比如:

func a() int {defer b()return 0
}

函数 b() 发生在 return 0 之后。

defer 是一个面向编译器的声明,会让编译器做两件事:

  1. 编译器会将 defer 声明编译为 runtime.deferproc(fn),这样运行时,会调用 runtime.deferproc,在 deferproc 中将所有 defer 挂到 Goroutine 的 defer 链上;
  2. 编译器会在函数 return 之前,增加 runtime.deferreturn 调用,开始处理前面挂在 defer 链上的所有 defer。

可见,defer 关键字会将指定的函数延迟到函数 return 语句之后执行,包括 Goroutine 的 return。defer 常用来释放数据库连接、文件打开句柄等资源的操作,有类似于 Python with Context 的作用。

defer 的用途之一:释放资源

由于 defer 的延迟特性,defer 常用在函数调用结束之后用于清理相关的资源,比如:

f, _ := os.Open(filename)
defer f.Close()

文件资源的释放会在函数调用结束之后借助 defer 语句自动执行,打开和释放必须相对应。

示例:

func CopyFile(dstName, srcName string) (written int64, err error) {src, err := os.Open(srcName)if err != nil {return}defer src.Close()dst, err := os.Create(dstName)if err != nil {return}defer dst.Close()return io.Copy(dst, src)
}

defer 的用途之二:执行 recover(恢复)

被 defer 的函数在 return 之后执行,这个时机点正好可以捕获函数抛出的 panic,因而 defer 的另一个重要用途就是执行 recover。

recover 只有在 defer 中使用才更有意义,如果在其他地方使用,由于程序已经调用结束并提前返回而无法有效捕捉错误。

package mainimport ("fmt"
)func main() {defer func() {if ok := recover(); ok != nil {fmt.Println("recover")}}()panic("error")
}

注意:defer 要放在 panic 执行之前。

defer 特性

多个 defer 的执行顺序

defer 的本质就是把关键字之后的函数执行压入一个栈(Stack)中延迟执行,所以当具有多个 defer 时,其执行顺序是后进先出(LIFO
)的。

defer func() { fmt.Println("1") }()
defer func() { fmt.Println("2") }()
defer func() { fmt.Println("3") }()

输出顺序是 3、2、1。

被 deferred 函数的参数在 defer 时确定

这是 defer 关键字的特点,一个函数被 defer 时,它的参数就已经确定了,即使 defer 之后参数发生了修改,也不会影响到 defer 时确定的数值。

func a() {i := 0defer fmt.Println(i)i++return
}

函数 a() 执行输出的是 0 而不是 1,因为 defer 时 i 的值是 0。

被 defer 的函数可以读取和修改带名称的返回值

被 defer 的函数是在 return 之后执行,可以修改带名称的返回值,例如下述示例中的返回值 i,在 defer 的 c() 中被修改了,所以返回的是 2。

func c() (i int) {defer func() { i++ }()return 1
}

Go 语言编程 — defer 关键字相关推荐

  1. generic泛型c语言编程,_Generic关键字及其语法和应用(C11标准),C语言_Generic详解...

    对接触过面向对象程序设计的程序员来讲,相信各位对泛型编程并不陌生.在 C11 标准中,_Generic 关键字可以让 C 语言也如同 C++ 等面向对象程序设计语言一样,使其支持轻量级的泛型编程设计. ...

  2. C 语言编程 — const 关键字

    目录 文章目录 目录 const 关键字 修饰常量 修饰指针 修饰函数形参 修饰函数返回值 const 关键字 const 是 Constant(常量)的简写,有 3 大作用: 修饰常量,说明该常量的 ...

  3. C 语言编程 — typedef 关键字

    目录 文章目录 目录 typedef 定义数据类型别名 定义无名结构体 typedef 和 const 结合使用的陷阱 typedef typedef 顾名思义,主要用于自定义一个数据类型,而数据类型 ...

  4. Go语言defer关键字

    Go语言的defer关键字用于延迟调用,下面是关于Go语言defer关键字的一些基础概念: 1. defer关键字用于注册延迟调用: 2. 这些调用直到包含当前该defer关键字的函数执行完了才会被执 ...

  5. 编程c语言中_是什么意思,计算机C语言中的关键字:double是什么意思?

    用户提问 RT 推荐答案 double:表示双精度字型. C语言中的关键字: auto :声明自动变量 break:跳出当前循环 case:开关语句分支 char :声明字符型变量或函数返回值类型 c ...

  6. Go语言编程入门超级指南

    Go语言编程入门超级指南 1.序言 Golang作为一门出身名门望族的编程语言新星,像豆瓣的Redis平台Codis.类Evernote的云笔记leanote等. 1.1 为什么要学习 如果有人说X语 ...

  7. 11 12 13c语言编程,C语言编程

    C语言编程 1.sscanf() sscanf()与scanf()类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源. 头文件:#include 格式:int ssc ...

  8. c语言编程常见问题解答 pdf,[编程语言]C语言常见问题集pdf pdf文件[1.35MB]-码姐姐下载...

    原著:Steve Summit 翻译:朱群英, 孙 云 修订版0.9.4, 2005年6月23日 目录 i 前言 xvii 1 声明和初始化 1 1.1 我如何决定使用那种整数类型?......... ...

  9. 如何在树莓派上进行python编程_设置并使用树莓派进行Python和C语言编程 (下)

    Python部落(www.freelycode.com)组织翻译, 禁止转载 关键字 条件关键字 下表列出了和条件语句有关的关键字和它们的简要描述 if用来决定将要执行哪条语句 else 可选,条件为 ...

最新文章

  1. cdc工具 postgresql_零编码打造异构数据实时同步系统——异构数据源CDC之2
  2. 精通python网络爬虫-精通Python网络爬虫:核心技术、框架与项目实战
  3. 将现有MySQL数据库改为大小写不敏感
  4. Golang闭包陷阱
  5. LP Wizard 10.5破解步骤
  6. 合并果子_tyvj1066_vijos1097_codevs1063_贪心+堆
  7. linux网口驱动实现(待续)
  8. 图幅号与经纬度的换算
  9. python 日期排序_python 日期排序
  10. 详解Python对象属性
  11. 7.3数据类型及内置方法(一)
  12. 需求分析文档、概要设计文档、详细设计文档
  13. 2021南航计算机专硕上岸经验贴
  14. Arduino UNO AT24C32进行单字节数据读写
  15. 临时的实验课记录+研究的代码+计算机文档目录管理
  16. 掘金站内 webpack 优秀文章汇总
  17. 汪磊老师整理的前端进阶课程目录
  18. Biotin-PEG2000-Pyrene 含有生物素和芘丁酸的PEG,Pyrene-PEG2000-Biotin
  19. 华为Vo5G技术GC方式下引入G
  20. stm32 F40x CCM数据区的使用

热门文章

  1. Swift3.0语言教程字符串与文件的数据转换
  2. plt转pdf软件_无须转Word也能轻松编辑PDF的软件,它来了!
  3. 钉钉自定义机器人python_使用钉钉自定义机器人发送舔狗日记[70行][python]
  4. 在docker中构建普通java程序_Docker入门-构建第一个Java程序
  5. eeglab中文教程系列(8)-选择数据的epochs并进行比较
  6. HTC开放Vive Tracker代码啦!
  7. 苹果遭火速打脸:照片扫描AI被逆向工程,英特尔工程师发现漏洞
  8. 谷歌上线AI新玩法:随手乱涂鸦,一键变怪兽
  9. 《小岛经济学--鱼、美元和经济的故事》Digest
  10. DOM渲染的详细过程 1