Go | 函式中的延遲執行技巧
💬 簡介
在 Go 語言中,defer
是一個強大的關鍵字,能夠讓某些函式延遲執行至包含該 defer
語句的函式返回之前。
這種特性讓 defer
在資源管理、錯誤處理、流程控制等場景中發揮重要作用。
本文將深入探討 defer
的特性與應用,幫助你更靈活地運用 defer
來提升程式的可讀性與安全性。
圖片來源:Gophers
🔎 defer
基礎概念
1️⃣ defer
的基本語法
defer
允許將某個函式的執行延遲到當前函式即將返回時才執行。
- 範例:輸出結果:
1
2
3
4
5
6
7
8
9package main
import "fmt"
func main() {
fmt.Println("開始執行")
defer fmt.Println("這是延遲執行的內容")
fmt.Println("結束執行")
}1
2
3開始執行
結束執行
這是延遲執行的內容📝
defer
會延遲執行到main
函式即將結束時才執行。
🚀 defer
的應用場景
1️⃣ 確保資源釋放
在處理檔案、資料庫連線等資源時,defer
可以確保即使程式中途出錯,資源仍能正確釋放。
- 範例:使用 defer 關閉檔案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("開啟檔案失敗:", err)
return
}
defer file.Close() // 確保在函式結束時關閉檔案
fmt.Println("正在處理檔案...")
}📝
defer file.Close()
確保即使函式提早返回,檔案仍然會被正確關閉。
2️⃣ 多個 defer
語句的執行順序
當函式中有多個 defer
語句時,它們會按照「後進先出」的順序執行(類似堆疊的結構)。
- 範例:多個
defer
的執行順序輸出結果:1
2
3
4
5
6
7
8
9
10package main
import "fmt"
func main() {
defer fmt.Println("第一個延遲執行")
defer fmt.Println("第二個延遲執行")
defer fmt.Println("第三個延遲執行")
fmt.Println("主程式執行")
}1
2
3
4主程式執行
第三個延遲執行
第二個延遲執行
第一個延遲執行📝
defer
採用 後進先出 (LIFO) 順序執行。
3️⃣ defer
在錯誤處理中的應用
defer
常與 recover()
配合使用,確保程式能在 panic
發生時進行適當的處理。
- 範例:捕獲
panic
並優雅恢復輸出結果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package main
import "fmt"
func main() {
defer handlePanic()
fmt.Println("開始執行...")
panic("發生錯誤!")
fmt.Println("這行程式碼不會執行")
}
func handlePanic() {
if r := recover(); r != nil {
fmt.Println("捕獲到 panic:", r)
}
}1
2開始執行...
捕獲到 panic: 發生錯誤!📝
recover()
用來捕獲panic
,避免程式異常終止。
🚨 後續文章將會提到
panic
與recover()
。
⚠️ 注意事項
📌 defer
與函式參數的求值時機
defer
語句中的函式參數會在 defer
被呼叫時 就計算,而不是在函式真正執行時才計算。
- ✅ 範例:函式參數的求值時機輸出結果:
1
2
3
4
5
6
7
8
9
10package main
import "fmt"
func main() {
x := 10
defer fmt.Println("延遲執行的 x:", x)
x = 20
fmt.Println("即時執行的 x:", x)
}1
2即時執行的 x: 20
延遲執行的 x: 10📝
defer fmt.Println("延遲執行的 x:", x)
時,x
的值已經固定為 10,即使後面x
變成 20,輸出仍是 10。
🎯 總結
defer
用於延遲執行函式,直到外層函式返回前執行。defer
適用於 資源釋放(如關閉檔案、解鎖互斥鎖等)。- 多個
defer
會 後進先出 (LIFO) 執行。 defer
可與recover()
搭配,用於錯誤處理。defer
內部函式的參數會 在defer
語句執行時 就被求值。
掌握 defer
,可以讓你的 Go 程式碼更 安全、整潔,並有效管理資源。
最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。
註:以上參考了
Go