1.1.1. 一、defer是什么:

defer是一个关键字。在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等) ,为了在函数执行完毕后,及时的释放资源,Go 的设计者提供 defer (延时机制)

1.1.2. 二、defer语句的执行顺序:

2.1、在函数中遇到defer语句先不执行。在函数执行完成后。在把defer语句按照流程从下往上执行

在一个函数中,当 go 执行到一个 defer 时,不会立即执行 defer 后的语句,而是将 defer 后的语句压入到一个栈中[暂时称该栈为 defer 栈],然后继续执行函数下一个语句。当函数执行完毕后,在从 defer 栈中,依次从栈顶取出语句执行(注:遵守栈 先入后出的机制)。注意:defer对执行流程的改变。只是在本函数内有用。也就是本函数执行完成之后,再把本函数全部的defer语句都要执行完成。

例子如下:

func add(num1 int,num2 int) int  {
    defer fmt.Println("defer1 ... num1=",num1)
    defer fmt.Println("defer2 ... num2=",num2)

    resp := num1 + num2
    defer fmt.Println("defer3 ... resp=",resp)

    return resp
}
func main() {
    add(1,9)
    defer fmt.Println("main 1.... ")
    defer fmt.Println("main 2............ ")
}

执行结果:

defer3 ... resp= 10

defer2 ... num2= 9

defer1 ... num1= 1

main 2............

main 1....

2.2、在 defer 将语句放入到栈时,也会将相关的值拷贝同时入栈。

例子如下:程序中即使在后面改变了num1、num2的值,defer中对应的值也不会改变。表示defer语句后是一个值拷贝。

func add(num1 int,num2 int) int  {
    defer fmt.Println("defer1 ... num1=",num1) //defer2 ... num2= 9
    defer fmt.Println("defer2 ... num2=",num2) //defer1 ... num1= 1

    num1++
    num2++
    return num1 + num2
}
func main() {
    add(1,9)
}

输出:

defer2 ... num2= 9

defer1 ... num1= 1

1.1.3. 三、defer的价值。

defer 最主要的价值是在,当函数执行完毕后,可以及时的释放函数创建的资源。

例子如下:可以在创建资源后直接用defer 关闭资源。defer 之后继续使用资源。 函数执行完成后执行defer关闭资源。

func test1()  {
    file,_:= os.OpenFile("文件名")
    defer file.Close()
    //其他代码。继续使用 file
}
func test2()  {
    db = sql.OpenDB()
    defer db.Close()
    //其他代码。继续使用 db
}
  • 在 golang 编程中的通常做法是,创建资源后,比如(打开了文件,获取了数据库的链接,或者是锁资源), 可以执行 defer file.Close() defer connect.Close() 。

  • 在 defer 后,可以继续使用创建资源。

  • 当函数完毕后,系统会依次从 defer 栈中,取出语句,关闭资源。

  • 这种机制,非常简洁,程序员不用再为在什么时机关闭资源而烦心。

results matching ""

    No results matching ""