go defer (go延迟函数)
go defer (go延迟函数)
Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此。根据GO LANGUAGE SPEC的说法:
A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking. defer语句调用一个函数,这个函数执行会推迟,直到外围的函数返回,或者外围函数运行到最后,或者相应的goroutine panic
换句话说,每当defer执行的时候,它后面的函数值(在go中函数是一个引用类型,是一等公民,可以赋值给变量)和函数参数会被求值,但是函数不会立即调用,直到(↑)上述三种情况发生。 这就是defer的全部内容,没了,剩下就是defer的best practice
函数不会立即调用
先从最简单的开始:
func readFile(fileName string){
f,err := os.Open(fileName)
if err!=nil {
return
}
defer f.Close()
var content [1024]byte
f.Read(content[:])
fmt.Printf("%s",content)
}
func main() {
readFile("test.data")
}
程序输出test.data前1024字节的内容。值得一提的是,类似这种open/close配对操作是defer的惯用法。 这个例子诠释了上面那句话的后半段
"但是函数不会被调用"
因为如果defer后面的f.Close()
没有延迟执行,那么文件描述符都关闭了,就不会读取到任何内容。
函数值和函数参数被求值,但函数不会立即调用
下面这个例子即将诠释上半段,它来自<>,稍作修改:
func trace(funcName string) func(){
start := time.Now()
fmt.Printf("function %s enter\n",funcName)
return func(){
log.Printf("function %s exit (elapsed %s)",funcName,time.Since(start))
}
} func foo(){
defer trace("foo()")()
time.Sleep(5*time.Second)
}
func main(){
foo()
foo()
}
/*
OUTPUT:
function foo() enter
function foo() exit (elapsed 5.0095471s)
function foo() enter
function foo() exit (elapsed 5.0005382s)
*/
为什么foo会输出enter
然后等待五秒左右再输出exit
? 因为正如我们说的,
defer后面的函数值和参数会被求值但是实际函数调用却要等到最后
这里函数值就是trace()
返回的匿名函数,函数参数当然就是字符串字面值"foo()", 对trace("foo()")
的求值会输出function foo() enter
, 实际函数调用trace("foo()")()
即输出function foo() exit(elapsed x.x)
会推迟到return执行(如果return会更新返回值变量,则会在更新后才执行defer的函数)。
杂项
多说一点,如果存在多个defer语句,最后的defer的函数的执行顺序与defer出现的顺序相反,如:
func main() {
func1 := func(){
fmt.Println("func1() execution deferred")
}
func2 := func(){
fmt.Println("func2() execution deferred")
}
defer func1()
defer func2()
fmt.Println("strat\nworking...")
}
/*
OUTPUT:
strat
working...
func2() execution deferred
func1() execution deferred
*/
go defer (go延迟函数)的更多相关文章
- go 学习笔记之解读什么是defer延迟函数
Go 语言中有个 defer 关键字,常用于实现延迟函数来保证关键代码的最终执行,常言道: "未雨绸缪方可有备无患". 延迟函数就是这么一种机制,无论程序是正常返回还是异常报错,只 ...
- Go 延迟函数 defer 详解
Go 延迟函数 defer 详解 Go 语言中延迟函数 defer 充当着 try...catch 的重任,使用起来也非常简便,然而在实际应用中,很多 gopher 并没有真正搞明白 defer.re ...
- Golang入门教程(十三)延迟函数defer详解
前言 大家都知道go语言的defer功能很强大,对于资源管理非常方便,但是如果没用好,也会有陷阱哦.Go 语言中延迟函数 defer 充当着 try...catch 的重任,使用起来也非常简便,然而在 ...
- go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数
温故知新不忘延迟基础 A "defer" statement invokes a function whose execution is deferred to the momen ...
- GO语言延迟函数defer用法分析
这篇文章主要介绍了GO语言延迟函数defer用法,较为详细的分析了GO语言的特性与具体用法,并给出了一个比较典型的应用实例,具有一定的参考借鉴价值,需要的朋友可以参考下 本文实例讲述了GO语言延迟 ...
- Python也可以拥有延迟函数
延迟函数defer 我们知道在Golang中有一个关键字defer,用它来声明在函数调用前,会让函数*延迟**到外部函数退出时再执行,注意,这里的退出含义:函数return返回或者函数panic退出 ...
- Delphi 延迟函数 比sleep 要好的多
转自:http://www.cnblogs.com/Bung/archive/2011/05/17/2048867.html //延迟函数:方法一 procedure delay(msecs:inte ...
- 延迟函数 比sleep效果好
sleep是会阻塞线程的 网上有些延迟函数测试下来还是会阻塞,而接下来推荐的代码则不会 1 2 3 4 5 6 7 8 9 procedure delay(dwMilliseconds:integ ...
- C# 延迟函数
#region 延迟函数 public static bool Delay(int delayTime) { DateTime now = DateTime.Now; int s; do { Time ...
随机推荐
- vue初级知识总结
从我第一篇博客的搭建环境开始,就开始学习vue了,一直想将这些基本知识点整理出来,但是一直不知如何下手,今天刚好实战了两个小demo,所以就想趁这机会将以前的一起整理出来,这是vue最基础的知识,我有 ...
- A computer hardware platform abstraction - part.1
intro Nowdays every electronic computer is based on Boole Algebra and Sequential Logic,So my post w ...
- 自己动手写Redis客户端(C#实现)4 - 整数回复
整数回复 整数回复就是一个以 ":" 开头, CRLF 结尾的字符串表示的整数. 比如说, ":0\r\n" 和 ":1000\r\n" 都 ...
- jsp运行原理及运行过程
JSP的执行过程主要可以分为以下几点: 1)客户端发出请求. 2)Web容器将JSP转译成Servlet源代码. 3)Web容器将产生的源代码进行编译. 4)Web容器加载编译后的代码并执行. 5)把 ...
- 利用python对excel进行数据剔除
需求分析: 判断excel2表中的某个唯一字段是否满足条件,如果满足条件,就在excel1中进行查询,若存在excel中,就将该数据进行剔除. python脚本的实现: from __future__ ...
- RGBA 和 opacity的区别
两者都可以设置透明度 区别 RGBA 只影响当前元素 opacity 后代会继承该css 值,暂时还没有办法清除该css 在线演示
- MySQL查看和修改表的存储引擎(转载+加点东西)
1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from YOUR_DB_NAME where name='YOU ...
- memcache 启动 储存原理 集群
一. windows下安装启动 首先将memcache的bin目录加入到Path环境变量中,方便后面使用命令: 然后执行 memcached –dinstall 命令安装memcache的服务: 然后 ...
- 关于websorm卡顿的问题
要是电脑不卡的话,使用webstorm真可谓是一种享受,但是随着项目的开展,文件逐渐增大,webstorm自然也会出现卡顿(毕竟缺点就是吃内存),这个时候我们可以增加Xms设置 Start1: 1 找 ...
- YiShop_做一个b2c商城要多少钱
[YiShop商城系统]做一个b2c商城要多少钱?是企业在做一个b2c商城最关心的问题.每个企业都是想用最少的钱做一个好的b2c商城.但企业这种想法可能在现实中是无法实现的.网站这种产品现实中是一分钱 ...