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