以身作則,解釋說明
defer 用於在函數返回前執行指定操作,如清理資源;參數在defer 時立即求值,函數按後進先出(LIFO)順序執行;1. 多個defer 按聲明逆序執行;2. 常用於文件關閉等安全清理;3. 可修改命名返回值;4. 即使發生panic 也會執行,適合用於recover;5. 避免在循環中濫用defer,防止資源洩漏;正確使用可提升代碼安全性和可讀性。
In Go, the defer
statement is a useful feature that allows you to schedule a function call to run just before the surrounding function returns. It's commonly used for cleanup actions like closing files, unlocking mutexes, or logging exit conditions.

Let's break it down with clear examples.
What defer
does
When you use defer
, the function call is pushed onto a stack and executed in last-in, first-out (LIFO) order when the function exits.

func main() { defer fmt.Println("World") fmt.Println("Hello") }
Output:
Hello World
Even though defer fmt.Println("World")
appears first, it runs after the fmt.Println("Hello")
because defer
delays execution until the function returns.

Defer with function calls and arguments
One key thing: arguments to a deferred function are evaluated immediately , but the function itself runs later.
func main() { i := 1 defer fmt.Println("Deferred:", i) // i is 1 now i = 2 fmt.Println("Immediate:", i) // prints 2 }
Output:
Immediate: 2 Deferred: 1
So:
-
i
is evaluated whendefer
is encountered (value is 1). - The
fmt.Println
runs later, but with the value captured at defer time.
Multiple defers: LIFO order
Deferred functions are executed in reverse order.
func main() { defer fmt.Println("First deferred") defer fmt.Println("Second deferred") defer fmt.Println("Third deferred") fmt.Println("Normal execution") }
Output:
Normal execution Third deferred Second deferred First deferred
This stack-like behavior is useful for nested cleanup operations.
Practical use: File handling
A common use case is closing files safely.
func readFile() { file, err := os.Open("data.txt") if err != nil { log.Fatal(err) } defer file.Close() // Guaranteed to run before function exits // Use the file... scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } }
Even if an error occurs or the function returns early, file.Close()
will be called thanks to defer
.
Defer and return values
defer
can even modify named return values:
func counter() (i int) { defer func() { i // increments the named return value }() return 5 // i becomes 5, then defer adds 1 → returns 6 }
func main() { fmt.Println(counter()) // Output: 6 }
This works because i
is a named return value, and the deferred closure captures it by reference.
You can't do this with regular return statements unless the return value is named.
Common gotchas
Don't defer in loops unnecessarily
for _, file := range files { f, _ := os.Open(file) defer f.Close() // Bad: all Close() calls happen at end, may exceed file limit }
Better: handle closing inside the loop or use a helper function.
Defer runs even if panic occurs
This makesdefer
perfect for recovery:defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) } }()
Summary
-
defer
schedules a function call to run before function returns. - Arguments are evaluated immediately; function runs later.
- Multiple defers execute in reverse order (LIFO).
- Great for cleanup: file closing, unlock, recover.
- Can modify named return values.
Used wisely,
defer
makes Go code cleaner and safer.Basically, if you need something done at the end — use
defer
.以上是以身作則,解釋說明的詳細內容。更多資訊請關注PHP中文網其他相關文章!
-

熱AI工具

Undress AI Tool
免費脫衣圖片

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

AdeadlockinJavaoccurswhentwoormorethreadsareblockedforever,eachwaitingforaresourceheldbytheother,typicallyduetocircularwaitcausedbyinconsistentlockordering;thiscanbepreventedbybreakingoneofthefournecessaryconditions—mutualexclusion,holdandwait,nopree
![您目前尚未使用附上的顯示器[固定]](https://img.php.cn/upload/article/001/431/639/175553352135306.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
Ifyousee"YouarenotusingadisplayattachedtoanNVIDIAGPU,"ensureyourmonitorisconnectedtotheNVIDIAGPUport,configuredisplaysettingsinNVIDIAControlPanel,updatedriversusingDDUandcleaninstall,andsettheprimaryGPUtodiscreteinBIOS/UEFI.Restartaftereach

Micronautisidealforbuildingcloud-nativeJavaapplicationsduetoitslowmemoryfootprint,faststartuptimes,andcompile-timedependencyinjection,makingitsuperiortotraditionalframeworkslikeSpringBootformicroservices,containers,andserverlessenvironments.1.Microna

理解JCA核心組件如MessageDigest、Cipher、KeyGenerator、SecureRandom、Signature、KeyStore等,它們通過提供者機制實現算法;2.使用SHA-256/SHA-512、AES(256位密鑰,GCM模式)、RSA(2048位以上)和SecureRandom等強算法與參數;3.避免硬編碼密鑰,使用KeyStore管理密鑰,並通過PBKDF2等安全派生密碼生成密鑰;4.禁用ECB模式,採用GCM等認證加密模式,每次加密使用唯一隨機IV,並及時清除敏

SpringDataJPA與Hibernate協同工作的核心是:1.JPA為規範,Hibernate為實現,SpringDataJPA封裝簡化DAO開發;2.實體類通過@Entity、@Id、@Column等註解映射數據庫結構;3.Repository接口繼承JpaRepository可自動實現CRUD及命名查詢方法;4.複雜查詢使用@Query註解支持JPQL或原生SQL;5.SpringBoot中通過添加starter依賴並配置數據源、JPA屬性完成集成;6.事務由@Transactiona

runtheapplicationorcommandasadministratorByright-clickingandSelecting“ runasAdministrator” toensureeleeleeleeleviledprivilegesareAreDranted.2.checkuseracccountcontontrol(uac)uac)

Pattern類用於編譯正則表達式,Matcher類用於在字符串上執行匹配操作,二者結合可實現文本搜索、匹配和替換;首先通過Pattern.compile()創建模式對象,再調用其matcher()方法生成Matcher實例,接著使用matches()判斷全字符串匹配、find()查找子序列、replaceAll()或replaceFirst()進行替換,若正則包含捕獲組,可通過group(n)獲取第n組內容,實際應用中應避免重複編譯模式、注意特殊字符轉義並根據需要使用匹配模式標誌,最終實現高效
