本文视频地址
一 defer是什么
日常咱们写如下的代码
var mu sync.Mutexmu.Lock()count++mu.Unlock()
这样的代码特点就是在函数中会申请一些资源并在函数退出前开释或敞开资源。函数的实现须要资源在函数退出时被及时地开释,无论函数的执行时按预期进行,还是抛错。为此,程序员须要对函数中的谬误里特地关注,在错误处理时不能遗记开释资源。这样让程序员须要思考的问题就会减少。同时多个资源开释怎么办?多个资源抛错怎么办?这样的逻辑将变得十分复杂,代码可读性也会极大升高,那程序的健壮性也是无奈保障的。
咱们看看Go语言中的defer如何解决下面的问题。
defer
1 只有在函数(办法)外部能力应用。
2 defer + 函数(办法),这些函数被称为deferred函数。defer将注册到其所在goroutine用于寄存deferred函数的栈数据结构中,这些deferred函数将在执行defer的函数退出前被按后进先出(LIFO)的程序调度执行。无论是执行到函数尾部返回,还是在某个粗偶解决分支显示renturn,还是panic,曾经存储到deferred函数栈中的函数都会被调度执行。因而,deferred函数是一个能够在任何状况下都能够为函数进行收尾工作。
var mu sync.Mutexmu.Lock()defer mu.Unlock()count++
下面的例子,咱们用defer改写一下,只有Lock办法被调用,就应用defer + Unlock办法让锁和解锁成对呈现,逻辑简化更加清晰。
二 defer 的常见用法
上面咱们通过deferred函数拦挡panic并复原了程序,持续运行:
func MakePanic(){ fmt.Println("制作一个panic") panic("111")}func Survive() { defer func() { if e:=recover();e!=nil{ fmt.Println(e) fmt.Println("我来援救你这个panic") } }() MakePanic()}func main() { Survive()}输入如下:制作一个panic111我来援救你这个panic
deferred函数在panic的状况下,仍能被执行。
三 defer 避 “坑” 指南
1 哪些函数能够作为deferred函数
办法和函数与defer无条件的联合,但有返回值的函数或办法,返回值会在deferred函数被调用的时候抛弃。
2 记得defer是后进先出的程序执行的
3 defer也是有性能损失的,为保障defer对整个利用的影响,尽量多进行测试,适当的应用defer。