博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go defer 知识点
阅读量:5978 次
发布时间:2019-06-20

本文共 2108 字,大约阅读时间需要 7 分钟。

在使用 Golang 开发程序时,我们可能会经常使用 defer 关键字,实现资源的回收,以及完成“收尾”工作。

执行顺序

若函数中有多个 defer ,执行顺序为 先进后出 ,可理解为栈。

package mainimport (	"fmt")func main() {	for i := 0; i < 3; i++ {		defer fmt.Println(i)	}}// 2// 1// 0复制代码

参数确定的时机

defer 在声明时会先计算确定其参数的值,推迟执行的仅是其函数体。

package mainimport "fmt"func print(a int) {	fmt.Println("value in deferred function", a)}func main() {	a := 5	defer print(a)	a = 10	fmt.Println("value before deferred function call", a)}// value before deferred function call 10// value in deferred function 5复制代码

在实际开发中,defer 的使用经常伴随着闭包和匿名函数的使用。

package mainimport "fmt"func main() {	for i := 0; i < 3; i++ {		// i 在每次循环中,都被确定其对应的值:0,1,2		defer fmt.Println(i)	}}// 2// 1// 0复制代码
package mainimport "fmt"func main() {	for i := 0; i < 3; i++ {		// 由于函数体只是被延迟执行,故在执行 defer 时,		// i 的值为 3		defer func() {			fmt.Println(i)		}()	}}// 3// 3// 3复制代码

return

在调用 return 时,会完成以下的事情:

  • 对返回值赋值
  • 调用 defer 表达式
  • 退出函数,并将返回值给调用函数
package mainimport (	"fmt")// 匿名返回值func func_naked_return() int {	defer func() {		fmt.Println("由于无法获取到匿名返回值变量,故无法对其进行修改")	}()	fmt.Println("对返回值赋值")	return 1}// 匿名返回值func func_naked_return_pointer() *int {	var r int	defer func() {		r++		fmt.Println("由于返回类型为指针,故可通过修改 r 间接修改匿名返回值")	}()	fmt.Println("对返回值赋值")	return &r}// 命名返回值func func_named_return() (r int) {	defer func() {		fmt.Println("在调用 defer 表达式时,已完成对返回值的赋值 ", r)		r = 2	}()	fmt.Println("对返回值赋值")	return 1}func main() {	fmt.Println("退出函数,将返回值给调用函数 ", func_naked_return())	fmt.Println("-------")	fmt.Println("退出函数,将返回值给调用函数 ", func_named_return())	fmt.Println("-------")	fmt.Println("退出函数,将返回值给调用函数 ", *func_naked_return_pointer())}// 对返回值赋值// 由于无法获取到匿名返回值变量,故无法对其进行修改// 退出函数,将返回值给调用函数  1// -------// 对返回值赋值// 在调用 defer 表达式时,已完成对返回值的赋值  1// 退出函数,将返回值给调用函数  2// -------// 对返回值赋值// 由于返回类型为指针,故可通过修改 r 间接修改匿名返回值// 退出函数,将返回值给调用函数  1复制代码
  • 匿名返回值变量无法被 defer 表达式所获取,故 defer 无法直接修改匿名返回值。但在返回值为指针类型的情况下,可通过修改指针所指向的值,实现间接修改匿名返回值

作用域

  • 当任意一条(主)协程发生 panic 时,会执行当前协程中 panic 之前已声明的 defer
  • 主动调用 os.Exit(int) 时,defer 将不执行
  • 在发生 panic 的(主)协程中,若没有一个 defer 调用 recover() 进行修复,则在执行完之前已声明的 defer 后,进程崩溃
  • defer 只对当前的(主)协程有效

参考文档

转载于:https://juejin.im/post/5c85eca8e51d45434c2c6906

你可能感兴趣的文章
在使用 Windows Update 检查更新时,系统没有提供下载 Windows 7 SP1 的选项
查看>>
miniWindbg 功能
查看>>
mysql基于mysqlslap的压力测试
查看>>
CF772E Verifying Kingdom
查看>>
rename设计思想(Perl版)
查看>>
第二次冲刺 第七天
查看>>
矩阵之矩阵乘法(转载)
查看>>
Python _内置函数3_45
查看>>
cf-Igor In the Museum (dfs)
查看>>
数据之路 Day4 - Python基础4
查看>>
使用openCV打开USB摄像头(UVC 小米micro接口)
查看>>
Luogu P3577 [POI2014]TUR-Tourism
查看>>
Scrapy框架的基本使用
查看>>
ActionResult,PartialViewResult,EmptyResult,ContentResult
查看>>
关于泛型类,泛型接口,泛型函数
查看>>
@pathvariable和@RequestParam的区别
查看>>
测试驱动开发
查看>>
C++操作符重载
查看>>
Redis实现分布式锁2
查看>>
【Udacity】线性回归方程 Regression
查看>>