Golang函式中defer的作用以及細節
defer是什麼?
在 Go語言中,可以使用關鍵字defer向函式註冊退出呼叫,即主函式退出時,defer後的函式才被呼叫。defer語句的作用是不管程式是否出現異常,均在函式退出時自動執行相關程式碼。
defer的用途
在函式中,程式設計師經常需要建立資源 ( 比如:資料庫連線、檔案控制代碼、鎖等 ) ,為了在函式執行完 畢後,及時的釋放資源, Go 的設計者提供 defer ( 延時機制 ) 。
package main import "fmt" //defer可以向函式註冊、退出呼叫,即當主調函式退出時,defer後的函式才被呼叫, // defer語句的作用就是不管程式是否出現異常,均在函式退出是自動執行相關程式碼 func sum(n1 int,n2 int) int{ //當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧) //當函式執行完畢後,再從defer棧 安裝先入後出的方式出棧執行 //defer 將語句放入到棧時,也會將相關的值拷貝同時入棧*** deferfmt.Println("ok1 n1=",n1)//defer3ok3n120 deferfmt.Println("ok2 n2=",n2) //defer2ok2 n210 //n1 ++ //n2 ++ res := n1 + n2 fmt.Println("ok3 res=",res)//1.ok1 returnres } funcmain(){ res :=sum(20,10) fmt.Println("res=",res) }
執行結果
結果分析:
從執行結果來看,res=30 是最先開始執行的部分,接下來是第二個defer n2為10 最後執行的是第一個defer n1為20 ,即當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧),當函式執行完畢後,再從defer棧,按照( 先入後出 )的方式出棧執行。
注意事項:
1) 當 go 執行到一個 defer 時,不會立即執行 defer 後的語句,而是將 defer 後的語句壓入到一個棧 中 [ 我為了講課方便,暫時稱該棧為 defer 棧 ], 然後繼續執行函式下一個語句。
2) 當函式執行完畢後,在從 defer 棧中,依次從棧頂取出語句執行 ( 注:遵守棧 先入後出的機制 ) ,
3) 在 defer 將語句放入到棧時,也會將相關的值拷貝同時入棧
package main import "fmt" //defer可以向函式註冊、退出呼叫,即當主調函式退出時,defer後的函式才被呼叫, // defer語句的作用就是不管程式是否出現異常,均在函式退出是自動執行相關程式碼 func sum(n1 int,n2 int) int{ //當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧) //當函式執行完畢後,再從defer棧 安裝先入後出的方式出棧執行 //defer 將語句放入到棧時,也會將相關的值拷貝同時入棧*** deferfmt.Println("ok1 n1=",n1)//defer3ok3n120 deferfmt.Println("ok2 n2=",n2) //defer2ok2 n210 n1 ++ n2 ++ res := n1 + n2 fmt.Println("ok3 res=",res)//1.ok1 returnres } funcmain(){ res :=sum(20,10) fmt.Println("res=",res) }
執行結果:
從結果看出n1++ ,n2++兩個的值未入相關defer的棧,即 defer 將語句放入到棧時,也會將相關的值拷貝同時入棧。