defer是什麼?程序員
在Go語言中,能夠使用關鍵字defer向函數註冊退出調用,即主函數退出時,defer後的函數才被調用。defer語句的做用是無論程序是否出現異常,均在函數退出時自動執行相關代碼。 數據庫
defer的用途bash
在函數中,程序員常常須要建立資源(好比:數據庫鏈接、文件句柄、鎖等) ,爲了在函數執行完 畢後,及時的釋放資源,Go 的設計者提供 defer (延時機制)。ide
package main import "fmt" //defer 能夠向函數註冊、退出調用,即當主調函數退出時,defer後的函數才被調用, // defer語句的做用就是無論程序是否出現異常,均在函數退出是自動執行相關代碼 func sum(n1 int,n2 int) int{ //當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧) //當函數執行完畢後,再從defer棧 安裝先入後出的方式出棧執行 //defer 將語句放入到棧時,也會將相關的值拷貝同時入棧*** defer fmt.Println("ok1 n1=",n1)//defer3 ok3 n1 20 defer fmt.Println("ok2 n2=",n2) //defer2 ok2 n2 10 //n1 ++ //n2 ++ res := n1 + n2 fmt.Println("ok3 res=",res)//1.ok1 return res } func main() { res :=sum(20,10) fmt.Println("res=",res) }
執行結果函數
結果分析:spa
從執行結果來看,res=30 是最早開始執行的部分,接下來是第二個defer n2爲10 最後執行的是第一個defer n1爲20 ,即當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧),當函數執行完畢後,再從defer棧,按照(先入後出)的方式出棧執行。設計
注意事項:blog
1) 當 go 執行到一個 defer 時,不會當即執行 defer 後的語句,而是將 defer 後的語句壓入到一個棧 中[我爲了講課方便,暫時稱該棧爲 defer 棧], 而後繼續執行函數下一個語句。資源
2) 當函數執行完畢後,在從 defer 棧中,依次從棧頂取出語句執行(注:遵照棧 先入後出的機制),it
3) 在 defer 將語句放入到棧時,也會將相關的值拷貝同時入棧
package main import "fmt" //defer 能夠向函數註冊、退出調用,即當主調函數退出時,defer後的函數才被調用, // defer語句的做用就是無論程序是否出現異常,均在函數退出是自動執行相關代碼 func sum(n1 int,n2 int) int{ //當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧) //當函數執行完畢後,再從defer棧 安裝先入後出的方式出棧執行 //defer 將語句放入到棧時,也會將相關的值拷貝同時入棧*** defer fmt.Println("ok1 n1=",n1)//defer3 ok3 n1 20 defer fmt.Println("ok2 n2=",n2) //defer2 ok2 n2 10 n1 ++ n2 ++ res := n1 + n2 fmt.Println("ok3 res=",res)//1.ok1 return res } func main() { res :=sum(20,10) fmt.Println("res=",res) }
執行結果:
從結果看出n1++ ,n2++兩個的值未入相關defer的棧,即defer 將語句放入到棧時,也會將相關的值拷貝同時入棧。