这黑色的光芒不是纯粹的分解之力,而是夹杂着一丝丝的毁灭之力。但正是这丝毁灭之力,却极为容易的便将那绝对黑暗给摧毁了。

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
",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
working...")
}
/*
OUTPUT:
strat
working...
func2() execution deferred
func1() execution deferred
*/

  

当前文章:http://hnhdqp.com/0ksiy/16713.html

发布时间:2018-12-15 13:11:36

德阳手工活在家兼职 义乌晚上兼职招聘 大学生暑假网络兼职 长春晚上兼职 qt网络兼职是真的吗 网络兼职发帖 潍坊赶集网招学生兼职话务员 投资5万做什么生意 现在投资创业新生意 50个适合县城做的生意

编辑:辛北道

相关新闻

中美最低工资该怎么比较

2018-12-15 09:53:34

十堰恼节鸭新能源有限公司

《新华苑》新片发布会展现不一YOUNG的力量

2018-12-15 05:10:53

太原骨吞电子有限公司

面首三千:女帝武则天到底有多少男宠

2018-12-15 03:58:43

营口页伺纯家庭服务有限公司

思迪博PIM:产品信息管理支持时装电商全渠道业务

2018-12-15 10:19:42

葫芦岛亲钦稻教育咨询有限公司

热门推荐

  • 科学家发现修复大脑新方法:中风有望通过药物治愈
  • 库克:恰当交接苹果“指挥权”是我最重要的责任之一
  • 三星中端新机J7 Prime2018曝光:搭载Exynos 7870处理器
  • 三星Note 8 vs. 苹果iPhone X:千兆LTE测试下载速度飙升
  • 多家华人店铺遭抢驻南非使馆提醒侨胞注意安全
  • 2018年放假安排时间表预测2018春节放假时间
  • 罗永浩微博暗示锤子新品:想卖啥写得相当明显
  • Nook GlowLight 3低调现身:能否打破Kindle垄断?
  • 团浙江省委言出必行 婚恋结交事业部挂牌建立
  • 海口一女子和男网友裸聊被对方截图勒索
  • 河北新闻网版权所有 本站点信息未经允许不得复制或镜像 法律顾问:2018什么赚钱 如何用电脑免费赚钱
  • 微信广告怎么做拆赚钱 copyright ? 2000 - 2016
  • 新闻热线:0311-67563366 广告热线:0311-67562966 新闻投诉:0311-67562994
  • 冀ICP备 09047539号-1 | 互联网新闻信息服务许可证编号:1312006002
  • 广播电视节目制作经营许可证(冀)字第101号|信息网络传播视听节目许可证0311618号
  • 游戏赚钱平台 08年金融危机谁赚钱了 网上干什么挣钱 短期赚钱的方法