本文摘自php中文网,作者尚,侵删。
Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此。
defer语句调用一个函数,这个函数执行会推迟,直到外围的函数返回,或者外围函数运行到最后,或者相应的goroutine panic
每当defer执行的时候,它后面的函数值(在go中函数是一个引用类型,是一等公民,可以赋值给变量)和函数参数会被求值,但是函数不会立即调用,直到(↑)上述三种情况发生。 这就是defer的全部内容,没了,剩下就是defer的best practice
函数不会立即调用
先从最简单的开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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()没有延迟执行,那么文件描述符都关闭了,就不会读取到任何内容。
函数值和函数参数被求值,但函数不会立即调用
下面这个例子即将诠释上半段,它来自<>,稍作修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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()
}
|
为什么foo会输出enter然后等待五秒左右再输出exit? 因为正如我们说的,
阅读剩余部分
相关阅读 >>
手撸Golang 基本数据结构与算法 栈
Golang核心编程
Golang 底层也用 Golang 吗?
Golang base64 斜杠 等号 问题
Go log
基于原论文,我实现了一个更全面的布谷鸟过滤器
Goland解析json获取指定字段内容
Golang 架构设计原则 迪米特法则
什么是量化交易|量化交易平台
值得推荐的五种自动化代码审查工具
更多相关阅读请进入《Go》频道 >>
老貘
一个与时俱进的Go编程知识库。
转载请注明出处:木庄网络博客 » go defer(go延迟函数)介绍