golang基礎--細說defer
阿新 • • 發佈:2018-07-12
遇到 cover 執行 時間 user running python pac use
defer 匿名函數特性
執行方式類似其它語言中的析構函數,在函數體執行結束後按照調用順序的
相反順序
逐個執行//執行順序相反 package main import "fmt" func main() { fmt.Println("a") defer fmt.Println("b") defer fmt.Println("c") } /*輸出 a c b */
- 即使函數發生
嚴重的錯誤
也會執行,類似於try...except 常用於 資源清理,文件關閉,解鎖以及記錄時間等操作
- 支持匿名函數的調用
通過於匿名函數配合可在return之後修改函數計算的結果
-如果函數體內某個變量作為defer時匿名函數的參數,則在定義defer時即已經獲得了拷貝,否則 則時引用某個變量的地址//支持匿名函數 package main import "fmt" func main() { for i := 0; i < 3; i++ { defer func() { //函數體內的變量傳遞到defer匿名函數 fmt.Println(i) //此時引用的時變量i的地址 }() } } /*輸出 3 3 3 */
- Go沒有異常機制,但有panic/recover模式來處理錯誤
Panic可以在任何地方引發
panic錯誤機制
//panic 錯誤機制,遇到panic語句後,後面不會再執行 package main import "fmt" func main() { A() B() C() } func A() { fmt.Println("func a") } func B() { panic("Panic B") } func C() { fmt.Println("func") } /*輸出 A()--> func a B()---> panic: Panic B --------------- goroutine 1 [running]: main.B() C() C:/Users/faily/Desktop/workspace/src/defer1.go:17 +0x40 main.main() C:/Users/faily/Desktop/workspace/src/defer1.go:8 +0x2c exit status 2 exit status 1 */
defer,配合recover及匿名函數處理程序出現的嚴重錯誤(panic語句),調過程序錯誤,繼續執行,類似於python語言中
try...except
,finally
語句.//defer,recover機制,處理panic引發的機制 package main import "fmt" func main() { A() B() C() } func A() { fmt.Println("func a") } func B() { defer func() { //defer函數放在panic之前 if err := recover(); err != nil { //註冊recover函數(判斷是否觸發panic錯誤),並判斷 fmt.Println("Recover in B") //如果程序出現panic,並且err不為nil(真實存在) } }() //記住,defer的匿名函數大括號後要加上() panic("Panic B") //跳過程序錯誤,繼續後面的執行。 } func C() { fmt.Println("func C") } /*輸出 A()--> func a B()--> Recover in B C()--> func C */
~~留一個問題,感興趣的小夥伴歡迎作答
運行以下代碼,並分析輸出結果
package main import "fmt" func main() { var fs = [4]func(){} //定義一個變量fs,類型為一個數組,數組元素的類型是 func for i := 0; i < 4; i++ { defer fmt.Println("defer i=", i) defer func() { fmt.Println("defer closure i=", i) }() fs[i] = func() { fmt.Println("closure i=", i) } } for _, f := range fs { f() } }
golang基礎--細說defer