概述
一個 defer 陳述句就是一個普通的函式或方法呼叫, defer 陳述句保證了不論是在正常情況下 (return 回傳), 還是非正常情況下 (發生錯誤, 程式終止),函式或方法都能夠執行,
主要特性
-
? 一個函式可定義多個
defer陳述句 -
?
defer運算式中的變數值在defer運算式定義時已經確定 -
?
defer運算式可以修改函式中的命名回傳值
主要作用
-
? 簡化例外處理 ( 使用
defer+recover),避免例外與控制流混合在一起 (try … catch … finally) -
? 在
defer做資源釋放和配置重置等收尾作業
語法規則
如果 defer 函式只有一行陳述句,可以省略 func() { ... } 代碼塊,否則就需要用 func() { ... } 代碼塊包起來,
多個 defer 執行順序
如果一個函式中注冊了多個 defer 函式,這些函式會按照 后進先出 的順序執行 (和 堆疊 的出堆疊順序一致),也就是最后注冊的 defer 函式會第一個執行,而第一個注冊的 defer 函式會最后執行,
例子
函式退出前列印字符
package main
func A() {
defer println("A 函式執行完成")
println("A 函式開始執行")
}
func B() {
defer println("B 函式執行完成")
println("B 函式開始執行")
}
func main() {
A()
B()
}
// $ go run main.go
// 輸出如下
/**
A 函式開始執行
A 函式執行完成
B 函式開始執行
B 函式執行完成
*/
關閉檔案句柄
package main
import (
"fmt"
"os"
)
func createFile(name string) *os.File {
file, err := os.Create(name)
if err != nil {
panic(err)
}
return file
}
func writeFile(file *os.File) {
n, err := file.WriteString("hello world")
if err != nil {
panic(err)
} else {
fmt.Printf("成功寫入 %d 個字符\n", n)
}
}
func closeFile(file *os.File) {
err := file.Close()
if err != nil {
panic(err)
}
}
func main() {
file := createFile("/tmp/defer_test.txt")
defer closeFile(file) // 獲取到檔案句柄后,第一時間注冊 defer 函式
writeFile(file)
}
// $ go run main.go
// 輸出如下
/**
成功寫入 11 個字符
*/
// $ cat /tmp/defer_test.txt
// 輸出如下
/**
hello world
*/
多個 defer 函式
package main
func A() {
defer println("第 1 個 defer 函式")
defer func() { // 這里為了演示 func() { ... } 的語法
defer println("第 2 個 defer 函式")
}()
defer println("第 3 個 defer 函式")
println("A 函式開始執行")
}
func main() {
A()
}
// $ go run main.go
// 輸出如下
/**
A 函式開始執行
第 3 個 defer 函式
第 2 個 defer 函式
第 1 個 defer 函式
*/
reference
- 1. Go 圣經 (https://book.douban.com/subject/27044219)
聯系我

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/540571.html
標籤:Go
上一篇:我的第一篇隨筆
