本文摘自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语言社区】源码篇--sync包map
Goland ide 安装终解
Golang 创建型设计模式 建造者模式
Golang 的内存管理(上篇)
聊聊Gost的hashset
模块一 Go语言基础知识-库源码文件
Go 语言入门系列:数组的使用
Golang程序设计——函数
手撸Golang 基本数据结构与算法 栈
Golang依赖注入工具wire指南
更多相关阅读请进入《Go》频道 >>
老貘
一个与时俱进的Go编程知识库。
转载请注明出处:木庄网络博客 » go defer(go延迟函数)介绍