defer 匿名函数特性
执行方式类似其它语言中的析构函数,在函数体执行结束后按照调用顺序的
相反顺序
逐个执行//执行顺序相反 package main import "fmt" func main() { fmt.Println("a") defer fmt.Println("b") defer fmt.Println("c") } /*输出 a c b */
- 即使函数发生
严重的错误
也会执行,类似于try...except 常用于 资源清理,文件关闭,解锁以及记录时间等操作
- 支持匿名函数的调用
通过于匿名函数配合可在return之后修改函数计算的结果
-如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则 则时引用某个变量的地址//支持匿名函数 package main import "fmt" func main() { for i := 0; i < 3; i++ { defer func() { //函数体内的变量传递到defer匿名函数 fmt.Println(i) //此时引用的时变量i的地址 }() } } /*输出 3 3 3 */
- Go没有异常机制,但有panic/recover模式来处理错误
Panic可以在任何地方引发
panic错误机制
//panic 错误机制,遇到panic语句后,后面不会再执行 package main import "fmt" func main() { A() B() C() } func A() { fmt.Println("func a") } func B() { panic("Panic B") } func C() { fmt.Println("func") } /*输出 A()--> func a B()---> panic: Panic B --------------- goroutine 1 [running]: main.B() C() C:/Users/faily/Desktop/workspace/src/defer1.go:17 +0x40 main.main() C:/Users/faily/Desktop/workspace/src/defer1.go:8 +0x2c exit status 2 exit status 1 */
defer,配合recover及匿名函数处理程序出现的严重错误(panic语句),调过程序错误,继续执行,类似于python语言中
try...except
,finally
语句.//defer,recover机制,处理panic引发的机制 package main import "fmt" func main() { A() B() C() } func A() { fmt.Println("func a") } func B() { defer func() { //defer函数放在panic之前 if err := recover(); err != nil { //注册recover函数(判断是否触发panic错误),并判断 fmt.Println("Recover in B") //如果程序出现panic,并且err不为nil(真实存在) } }() //记住,defer的匿名函数大括号后要加上() panic("Panic B") //跳过程序错误,继续后面的执行。 } func C() { fmt.Println("func C") } /*输出 A()--> func a B()--> Recover in B C()--> func C */
- defer,匿名函数,变量传递,数组array,for循环综合
运行以下代码,并分析输出结果
package main import "fmt" func main() { var fs = [4]func(){} //定义一个变量fs,类型为一个数组,数组元素的类型是匿名函数func for i := 0; i < 4; i++ { defer fmt.Println("defer i=", i) //defer,遵循的是先进后出,所以for循环,最后执行这一句,i作为变量,正常传递 defer func() { fmt.Println("defer closure i=", i) }() // i从外部传递进defer匿名函数中,作为变量而非匿名函数参数,此时引用的是i的内存地址(只会引用i的最后值) fs[i] = func() { fmt.Println("closure i=", i) } //为fs数组索引赋值,i传递进匿名函数并没有作为参数,所以i引用的是i的内存地址(只会引用i的最后值) fmt.Println(i) } for n, f := range fs { // for 循环数组,执行每一个元素(匿名函数) fmt.Println(n) f() } } /*输出 n=0 closure i= 4 n=1 closure i= 4 n=2 closure i= 4 n=3 closure i= 4 ------------------------ defer closure i= 4 defer i= 3 defer closure i= 4 defer i= 2 defer closure i= 4 defer i= 1 defer closure i= 4 defer i= 0 */
分析结果,详见代码注释