Go語言的defer:確保後置操作的執行

更新於 發佈於 閱讀時間約 4 分鐘


raw-image

👨‍💻簡介

當我們在寫程式時,有時候會需要在程式結束時關閉某些資源,而defer這個關鍵字,可以讓你輕鬆的實現,下面來簡單介紹一下defer以及常用的範例。,它為程式設計師提供了一種簡單而強大的工具,用於管理資源和確保程式的正確執行。在本篇文章中,我們將深入探討Go語言中的defer,並提供一些實際的程式碼範例,以幫助你理解它的工作原理以及如何運用它來提高程式的可讀性和可維護性。

什麼是defer

defer是一個關鍵字,用來延遲函數的執行,直到包含它的函數執行完畢。這代表你可以在函數中的任何位置使用defer來安排某個操作,並確保它將在函數返回之前執行。defer通常用於執行一些清理或資源回收的操作。

package main

import "fmt"
func main() {
defer fmt.Println("World")
fmt.Print("Hello, ")
}

使用方式也很簡單,在要執行的函數前面加上defer就完成了,所以上面的範例會印出 Hello World

Defer的特性

  1. 延遲執行defer 語句允許你安排一段程式碼,使它在包含它的函數返回之前執行,無論函數是否正常返回或出現錯誤。
  2. 堆疊特性:多個 defer 語句按照後進先出(LIFO)的順序執行,這意味著最後一個被延遲的語句會最先執行。
package main

import "fmt"
func main() {
fmt.Println("Start")
defer fmt.Println("Deferred 1")
defer fmt.Println("Deferred 2")
fmt.Println("End")
}

根據defer特性的後進先出,輸出會是下面這個樣子

Start
End
Deferred 2
Deferred 1

Defer的限制

  1. 延遲的函數必須是無參數函數:你只能延遲無參數的函數調用,因為 defer 不允許傳遞參數。
  2. 順序性defer 語句的效果在函數內是有限定範圍的,它只在包含它的函數範圍內有效,無法跨函數使用。

常見用法

資源清理

最常見的用途之一是在函數返回前關閉文件、釋放鎖、關閉資料庫連接等,以確保資源被正確釋放。

func readFile(filename string) (string, error) {
file, err := os.Open(filename)
if err != nil {
return "", err
}
defer file.Close()

// 讀取文件內容
// ...

return content, nil
}

在上述範例中,defer 用於確保文件在函數返回之前被正確關閉。

記錄錯誤

defer 可以用於處理錯誤,例如記錄錯誤訊息或回滾交易,並確保它們不會被遺漏。

func doSomething() error {
err := performOperation()
if err != nil {
defer logError(err)
}

// 其他操作
return nil
}

func logError(err error) {
fmt.Println("Error:", err)
}

在上述範例中,defer 用於記錄錯誤,無論函數是否正常返回。

小結

defer是Go語言中一個強大的功能,通常在撰寫對db的連接時我都會在下一行使用defer進行db的關閉連接,確保這些操作在函數返回之前執行。這使得程式更容易閱讀和維護,並有助於避免資源洩漏等問題,它可用於資源管理、錯誤處理和性能優化等多種情況下,提高程式的可讀性和可維護性。

📚Reference

留言
avatar-img
留言分享你的想法!
阿Han-avatar-img
2024/01/30
寫的非常清楚, 謝謝你的分享
wang alan-avatar-img
發文者
2024/04/24
阿Han 謝謝你的閱讀
avatar-img
Alan的開發者天地
18會員
83內容數
golang
Alan的開發者天地的其他內容
2023/10/04
👨‍💻 簡介 最近想要透過小實作來撰寫筆記,達到做中學的效果,因此就來實作個小爬蟲順便結合前面學到的package做一個小複習。
Thumbnail
2023/10/04
👨‍💻 簡介 最近想要透過小實作來撰寫筆記,達到做中學的效果,因此就來實作個小爬蟲順便結合前面學到的package做一個小複習。
Thumbnail
2023/09/28
👨‍💻簡介 今天來介紹一個自己開發後端蠻常用的一個 package,promptui,拿來做menu真的很方便,promptui有兩個主要的輸入模式: Prompt:跳出單行使用者輸入。 Select:提供一個選項列表供使用者選擇。
Thumbnail
2023/09/28
👨‍💻簡介 今天來介紹一個自己開發後端蠻常用的一個 package,promptui,拿來做menu真的很方便,promptui有兩個主要的輸入模式: Prompt:跳出單行使用者輸入。 Select:提供一個選項列表供使用者選擇。
Thumbnail
2023/09/26
👨‍💻 簡介 在處理string時,正則表達式是一個非常有用的工具。Go語言的regexp package 可以使用正則表達式,用來執行如檢查string是否匹配某個模式、提取匹配的subString等操作。
Thumbnail
2023/09/26
👨‍💻 簡介 在處理string時,正則表達式是一個非常有用的工具。Go語言的regexp package 可以使用正則表達式,用來執行如檢查string是否匹配某個模式、提取匹配的subString等操作。
Thumbnail
看更多
你可能也想看
Thumbnail
大家好,我是一名眼科醫師,也是一位孩子的媽 身為眼科醫師的我,我知道視力發展對孩子來說有多關鍵。 每到開學季時,診間便充斥著許多憂心忡忡的家屬。近年來看診中,兒童提早近視、眼睛疲勞的案例明顯增加,除了3C使用過度,最常被忽略的,就是照明品質。 然而作為一位媽媽,孩子能在安全、舒適的環境
Thumbnail
大家好,我是一名眼科醫師,也是一位孩子的媽 身為眼科醫師的我,我知道視力發展對孩子來說有多關鍵。 每到開學季時,診間便充斥著許多憂心忡忡的家屬。近年來看診中,兒童提早近視、眼睛疲勞的案例明顯增加,除了3C使用過度,最常被忽略的,就是照明品質。 然而作為一位媽媽,孩子能在安全、舒適的環境
Thumbnail
我的「媽」呀! 母親節即將到來,vocus 邀請你寫下屬於你的「媽」故事——不管是紀錄爆笑的日常,或是一直想對她表達的感謝,又或者,是你這輩子最想聽她說出的一句話。 也歡迎你曬出合照,分享照片背後的點點滴滴 ♥️ 透過創作,將這份情感表達出來吧!🥹
Thumbnail
我的「媽」呀! 母親節即將到來,vocus 邀請你寫下屬於你的「媽」故事——不管是紀錄爆笑的日常,或是一直想對她表達的感謝,又或者,是你這輩子最想聽她說出的一句話。 也歡迎你曬出合照,分享照片背後的點點滴滴 ♥️ 透過創作,將這份情感表達出來吧!🥹
Thumbnail
👨‍💻簡介 昨天講到Goroutine的橋梁aka傳話筒 — Channel,那要怎麼知道對方有收到訊息,我的紙條有送到對方手上呢? 今天就是要來介紹幾種Goroutine的確定完成工作的幾種方式。
Thumbnail
👨‍💻簡介 昨天講到Goroutine的橋梁aka傳話筒 — Channel,那要怎麼知道對方有收到訊息,我的紙條有送到對方手上呢? 今天就是要來介紹幾種Goroutine的確定完成工作的幾種方式。
Thumbnail
👨‍💻簡介 在日常生活中,如果能同時做很多事情,效率肯定大大提升,那麼在Go語言中,該如何做到呢,答案就是今天的主角Goroutine了,在Go語言中,讓併發變得簡單的強大工具,今天就是來給他一個快速介紹。
Thumbnail
👨‍💻簡介 在日常生活中,如果能同時做很多事情,效率肯定大大提升,那麼在Go語言中,該如何做到呢,答案就是今天的主角Goroutine了,在Go語言中,讓併發變得簡單的強大工具,今天就是來給他一個快速介紹。
Thumbnail
👨‍💻簡介 當我們在寫程式時,有時候會需要在程式結束時關閉某些資源,而defer這個關鍵字,可以讓你輕鬆的實現,下面來簡單介紹一下defer以及常用的範例。,它為程式設計師提供了一種簡單而強大的工具,用於管理資源和確保程式的正確執行。
Thumbnail
👨‍💻簡介 當我們在寫程式時,有時候會需要在程式結束時關閉某些資源,而defer這個關鍵字,可以讓你輕鬆的實現,下面來簡單介紹一下defer以及常用的範例。,它為程式設計師提供了一種簡單而強大的工具,用於管理資源和確保程式的正確執行。
Thumbnail
你有沒有想過,當你在玩電子遊戲時,每次過關或失敗後,遊戲是如何保存你的遊戲進度的呢? 🎮 或者當你正在編輯文檔時,"Undo" 功能又是如何工作的? 这些都可以通過備忘錄模式來實現!
Thumbnail
你有沒有想過,當你在玩電子遊戲時,每次過關或失敗後,遊戲是如何保存你的遊戲進度的呢? 🎮 或者當你正在編輯文檔時,"Undo" 功能又是如何工作的? 这些都可以通過備忘錄模式來實現!
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 在這篇文章裡,會簡單介紹幾個關鍵的基本概念和語法結構,加快上手這門程式語言。
Thumbnail
👨‍💻簡介 在這篇文章裡,會簡單介紹幾個關鍵的基本概念和語法結構,加快上手這門程式語言。
Thumbnail
有多種情況下我們需要從API取消請求: 如果我們正在建立一個支付系統,並且請求一直進行,但使用者希望立即取消這筆訂單。這就是為什麼開發者會建立這個功能的原因。 從電子商務購買商品。使用者意外關閉了頁面,無法立即返回上一頁。 訂閱取消。 ......等等 這將對對這個系統沒有信心的使用者產生影響。因
Thumbnail
有多種情況下我們需要從API取消請求: 如果我們正在建立一個支付系統,並且請求一直進行,但使用者希望立即取消這筆訂單。這就是為什麼開發者會建立這個功能的原因。 從電子商務購買商品。使用者意外關閉了頁面,無法立即返回上一頁。 訂閱取消。 ......等等 這將對對這個系統沒有信心的使用者產生影響。因
Thumbnail
執行以上程式碼,然後看到了這個結果: 為什麼「延遲0秒」的函式寫在上方,但在console印出的結果,它還是被排在第二順位? 利用AC教材提供的youtube演講連結一窺究竟: 演講提供了更多JS的細節概念,身為JS新手的我還在消化,但若針對教案提出的問題來回答,加上利用google大神查到MDN的
Thumbnail
執行以上程式碼,然後看到了這個結果: 為什麼「延遲0秒」的函式寫在上方,但在console印出的結果,它還是被排在第二順位? 利用AC教材提供的youtube演講連結一窺究竟: 演講提供了更多JS的細節概念,身為JS新手的我還在消化,但若針對教案提出的問題來回答,加上利用google大神查到MDN的
Thumbnail
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
Thumbnail
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News