- defer
defer是go语言里的一种语句,用来将一个函数压入一个函数栈中,等声明他的函数里的所有语句都执行完后,才调用栈中的函数。如果有多条defer语句则遵循栈的先入后出机制来依次调用。defer后面的函数在压入栈时其的参数就已经被赋值。因为defer总是在函数执行完其他语句后被调用,这种特性通常用于关闭一个打开的资源,或者关闭一个锁
- panic
当函数运行中内部发生一些错误时,例如数组越界,就会产生一个恐慌,这时程序会中断,这个panic会被返回给函数调用方。值得一提的是产生panic后函数的defer语句还是会正常执行,对于该函数的调用方也是同样,但是其他panic后执行的正常语句都会被中断
- recover
当我们产生一个panic后,这个panic可以被recover()函数捕获,注意,recover()函数只能用在defer语句中。当我们捕获了recover后就可以,对这个错误进行格式化。有点类于其他编程语言中的catch语句。这种捕获掉panic的好处是我们上层函数可不受这个panic影响,可以正常执行。
用法示例
package main import "fmt" func main() { f() fmt.Println("Returned normally from f.") } func f() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) } }() fmt.Println("Calling g.") g(0) fmt.Println("Returned normally from g.") } func g(i int) { if i > 3 { fmt.Println("Panicking!") panic(fmt.Sprintf("%v", i)) } defer fmt.Println("Defer in g", i) fmt.Println("Printing in g", i) g(i + 1) }
输出的结果:
Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
Recovered in f 4
Returned normally from f.