1. 程式人生 > >Golang的defer

Golang的defer

什麽 print 只有一個 test post package 數據 析構函數 程序設計

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