Golang的defer

Posted 寻觅beyond

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang的defer相关的知识,希望对你有一定的参考价值。

defer后面的函数在Go程序设计语言中被称为延迟函数,为什么叫延迟呢?因为这个defer函数的存在于一个函数之中(包括main函数),defer函数执行的时机是在 包含他的那个函数(上一层函数)将要执行完之前的最后一步,即函数最后一条语句执行完了,然后在执行这个defer函数,如果同一个函数内部有多个defer的函数,那么,这些个defer函数的执行顺序按照栈的后进先出,最后定义的defer函数最先执行,最先定义的defer函数最后执行。

类似于 有一个人生了儿子(可能是生了几个儿子,也可能只有一个),这个人的儿子都特别懒,在他活着的时候,他的儿子什么事都不干,等他快死的时候,吩咐一大堆事情,需要让他儿子们来处理,如果只有一个儿子,那这个就好办,所有的事情都得让他处理,如果又多个儿子,那么,老大推给老二,老二推给老三,老三做了一些事就跑了,还留了一些给老二处理,老二处理了一些也跑了,剩下的全让老大处理了,等老大处理完之后,他老子才放心的闭眼死去。 在这个例子中,这些个儿子就是延迟函数。

先看一个简单的例子:

package main
import "fmt"
func main(){
    defer func(){
        fmt.Println("run last")
    }()
    //注意defer的函数后面一定要加圆括号,不然就是定义函数,而不会执行函数

    fmt.Println("run first")
}

  在上面这个例子中,包含defer函数的 函数是main函数,所以在main()函数执行完毕之后(不能说main函数执行完毕,应该说已经顺序执行完除了defer函数以外的所有语句),才执行defer函数,所以运行结果如下:

run first
run last

  

然后看下面这个例子:

package main
import "fmt"
func test(){
    fmt.Println("One")
    defer func(){
        fmt.Println("two")
    }()
    defer func(){
        fmt.Println("three")
    }()
}
func main(){
    test()
    fmt.Println("run first")
}

  上面这个例子中test函数包含在main()中,test函数中包含两个延迟函数,所以正常语句执行完之后,应该先执行第二个延迟函数,然后执行第一个延迟函数,然后test函数执行完毕后,在顺序执行test函数后面的语句。

One
three
two
run first

  

  

在看一个例子:

package main
import "fmt"
func test(){
    fmt.Println("One")
    defer func(){
        fmt.Println("two")
    }()
    defer func(){
        fmt.Println("three")
    }()
}
func main(){
    defer test()  #与上面一个例子的区别,这里test函数是延迟函数
    fmt.Println("run first")
}

  因为test函数此时作为延迟函数,那么test函数在main函数中最后执行,执行test的时候,因为test中又有延迟函数,仍旧遵守上面的顺序,所以执行的结果如下:

run first
One
three
two

  

  延迟函数类似于其他面向对象语言中的析构函数,只是很类似,不要混为一谈。延迟通常用来做一些收尾工作,给他的主子擦屁股,比如关闭打开的文件,或者一些连接状态,亦或者清楚一些数据。。。。。

以上是关于Golang的defer的主要内容,如果未能解决你的问题,请参考以下文章

golang:defer执行顺序

Golang中defer的三个实战要点

Golang基础defer执行顺序

golang中defer的些许总结

Golang 之轻松化解 defer 的温柔陷阱

Golang中巧用defer进行错误处理