理解Go語言中的defer

引言

Go有許多在其他編程語言中可以找到的常見控制流關鍵字,例如ifswitchfor等。defer是其他大多數編程語言中沒有的關鍵字,盡管它不太常見,但你很快就會看到它在你的程序中有多么有用。

defer語句的主要用途之一是清理資源,例如打開的文件,網絡連接和數據庫句柄。在程序使用完這些資源后,關閉它們是很重要的,以避免耗盡程序的限制,并允許其他程序訪問這些資源。通過將關閉文件/資源的調用保持在接近open調用的位置,defer使我們的代碼更清晰,更不容易出錯。

在本文中,我們將學習如何正確使用defer語句來清理資源,以及在使用defer時所犯的幾個常見錯誤。

什么是defer語句

defer語句將defer關鍵字后面的[function]調用添加到棧上。當添加它們的函數返回時,該堆棧上的所有調用都會被調用。因為這些調用是放在棧上的,所以它們是按照后進先出的順序調用的。

讓我們通過打印一些文本來看看defer是如何工作的:

main.go

package mainimport "fmt"func main() {defer fmt.Println("Bye")fmt.Println("Hi")
}

main函數中,我們有兩個語句。第一個語句以defer關鍵字開始,接著是print語句,打印出Bye。下一行打印出Hi

如果運行這個程序,會看到如下輸出:

OutputHi
Bye

注意,首先打印的是Hi。這是因為任何以defer關鍵字開頭的語句直到使用defer的函數結束時才會被調用。

再看一下這個程序,這次我們將添加一些注釋來幫助解釋所發生的事情:

main.go

package mainimport "fmt"func main() {// defer statement is executed, and places// fmt.Println("Bye") on a list to be executed prior to the function returningdefer fmt.Println("Bye")// The next line is executed immediatelyfmt.Println("Hi")// fmt.Println*("Bye") is now invoked, as we are at the end of the function scope
}

理解defer的關鍵是,當defer語句執行時,延遲函數的參數會立即計算。當defer執行時,它將后面的語句放在一個列表中,以便在函數返回之前調用。

盡管這段代碼說明了defer的運行順序,但這并不是編寫Go程序時使用它的典型方式。我們更有可能使用defer來清理資源,例如文件句柄。接下來讓我們看看如何做到這一點。

使用defer來清理資源

在Go中使用defer來清理資源是很常見的。讓我們首先來看一個程序,它將字符串寫入文件,但不使用defer來處理資源清理:

main.go

package mainimport ("io""log""os"
)func main() {if err := write("readme.txt", "This is a readme file"); err != nil {log.Fatal("failed to write file:", err)}
}func write(fileName string, text string) error {file, err := os.Create(fileName

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210147.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210147.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210147.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在AWS Lambda上部署EC2編譯的FFmpeg工具——自定義層的方案

大綱 1 確定Lambda運行時環境1.1 Lambda系統、鏡像、內核版本1.2 運行時1.2.1 Python1.2.2 Java 2 環境準備2.1 創建EC2實例 3 編譯FFmpeg3.1 連接EC2 4 編譯5 上傳S3存儲桶5.1 創建S3桶5.2 創建IAM策略5.3 創建IAM角色5.4 EC2關聯角色5.5 修改桶策略5.6 打包并上傳 6 創建Lamb…

智能優化算法應用:基于海鷗算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用:基于海鷗算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用:基于海鷗算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.海鷗算法4.實驗參數設定5.算法結果6.參考文獻7.MA…

【nuxt3】cannot read preperties of null (reading ‘$nuxt‘)

問題描述 vue3 中,通過 createVNode 創建子組件實例時,發現子組件無法獲取到父組件中的 router、store 信息,一旦子組件使用就會報錯。 問題原因 通過控制臺斷點調試,發現時 appContext 值為空導致的。懷疑是創建子組件的時候&a…

海外地區開啟IPV6無法訪問服務器問題

前言 最近有海外地區的用戶反饋無法訪問公司的網絡,無法下載應用和系統進行升級。了解到瀏覽器可以正常訪問公司域名,谷歌,油管等都能正常使用。日志分析GET請求服務器數據時沒有得到應答,最終查詢網絡相關修改確認與網絡IPV6有關…

掌握游戲開發的全方位知識:這些內容你一定要知道

游戲開發是一項涉及多學科的綜合性工作,從游戲設計到編程、美術、音頻、測試等多個方面都需要開發者具備廣泛的知識。以下是進行游戲開發時需要掌握的主要知識領域。 首先,游戲設計是整個過程的基石。這包括游戲機制和玩法設計、關卡設計、用戶界面&…

表示你的shell未被正確配置以使用conda activate--換成清華源anaconda

1 CommandNotFoundError: Your shell has not been properly configured to use conda activate. If using conda activate from a batch script, change your invocation to CALL conda.bat activate.To initialize your shell, run$ conda init <SHELL_NAME>這個錯誤提…

uniapp-獲取手機型號

要獲取當前設備的手機型號&#xff0c;您可以使用uni-app提供的uni.getSystemInfo() API來實現此目的。 代碼示例&#xff1a; uni.getSystemInfo({success: function(res) {console.log("手機型號&#xff1a;" res.platform)} })該方法會返回一個包含設備信息的…

JFrog推出面向Hugging Face的原生集成,為 ML 模型提供強大支持,實現DevOps、安全和AI的協調統一

2023年12月5日 —— 流式軟件公司、企業軟件供應鏈平臺提供商JFrog推出ML模型管理功能&#xff0c;這是業界首套旨在簡化機器學習&#xff08;ML&#xff09;模型管理和安全性的功能。JFrog 平臺中的全新ML模型管理功能使AI交付與企業現有的 DevOps 和 DevSecOps 實踐保持一致&…

計算機評價的主要性能指標

對計算機評價的主要性能指標如下&#xff1a; 1&#xff0e;時鐘頻率&#xff08;主頻&#xff09; 主頻是計算機的主要性能指標之一&#xff0c;在很大程度上決定了計算機的運算速度。CPU 的工作節拍是由主時鐘來控制的&#xff0c;主時鐘不斷產生固定頻率的時鐘脈沖&#xff…

一個簡單的可視化的A星自動尋路

一個簡單的應用場景&#xff0c;流程圖連線 源碼&#xff1a; addExample("A星路徑查找", function () {return {template: <div><div ref"main"></div></div>,data() { return {}; },computed: {},methods: {},mounted() {var c…

Python中的比較兩個字符串

更多資料獲取 &#x1f4da; 個人網站&#xff1a;ipengtao.com 在Python編程中&#xff0c;字符串比較是一項常見且關鍵的操作&#xff0c;涵蓋了諸多方法和技巧。比較兩個字符串是否相等、大小寫是否一致&#xff0c;或者在一個字符串中尋找特定的子字符串&#xff0c;都是日…

征途漫漫:汽車MCU的國產替代往事

01.西雁東飛&#xff0c;南下創業 1985年&#xff0c;山東大學物理系畢業的周生明加入878廠&#xff08;“北霸天”&#xff09;參與MOS電路研發&#xff0c;隨后幾年&#xff0c;大洋彼岸的英特爾相繼推出CPU 386\486、奔騰系列等產品。在摩爾定律的凸顯、進口和走私的劇烈沖…

基于Java房屋租賃管理系統

基于Java房屋租賃管理系統 功能需求 1、房源信息管理&#xff1a;系統需要能夠記錄和管理所有房源的詳細信息&#xff0c;包括房屋地址、房屋面積、租金、付款方式、房屋類型等。管理員應該可以添加、編輯和刪除房源信息。 2、租戶信息管理&#xff1a;系統需要能夠記錄和管…

class067 二維動態規劃【算法】

class067 二維動態規劃 code1 64. 最小路徑和 // 最小路徑和 // 給定一個包含非負整數的 m x n 網格 grid // 請找出一條從左上角到右下角的路徑&#xff0c;使得路徑上的數字總和為最小。 // 說明&#xff1a;每次只能向下或者向右移動一步。 // 測試鏈接 : https://leetcode…

<JavaEE> 經典設計模式之 -- 線程池

目錄 一、線程池的概念 二、Java 標準庫中的線程池類 2.1 ThreadPoolExecutor 類 2.1.1 corePoolSize 和 maximumPoolSize 2.1.2 keepAliveTime 和 unit 2.1.3 workQueue 2.1.4 threadFactory 2.1.5 handler 2.1.6 創建一個參數自定義的線程池 2.2 Executors 類 2.3…

go學習筆記(17)Blob and ArrayBuffer

最近在學習go websocket的時候&#xff0c;在學習實驗過程遇到一個比較奇怪問題。為什么我的數據返回是blob&#xff0c;而不是arrayBuffer&#xff1f;百思不得其解。 直到同事打包的時候微信小游戲遇到了一個報錯。FileReader不支持。 經過在社區查詢&#xff0c;官方答復是…

Qt之QCache和QContiguousCache

一.QCache QCache在構造的時候指定了緩存中允許的最大成本,也就是如下構造函數中的參數maxCost。默認情況下,QCaches maxCost() 是100。 QCache(int maxCost = 100) ~QCache() void clear() bool contains(const Key &key) const int count() const bool insert(const …

[原創] 電源芯片輸出端的紋波測試

網上有很多文章講解&#xff0c;電源芯片的紋波測試&#xff0c;原理圖各種講解&#xff0c;理論有余&#xff0c;實質性測試細節不夠細致&#xff0c;想寫一些測試步驟&#xff0c;作為分享和記錄。 1、設置示波器參數 1.1 校準示波器 1.2 探頭按鈕推到X1&#xff08;代表波…

[RoBERTa]論文實現:RoBERTa: A Robustly Optimized BERT Pretraining Approach

文章目錄 一、完整代碼二、論文解讀2.1 模型架構2.2 參數設置2.3 數據2.4 評估 三、對比四、整體總結 論文&#xff1a;RoBERTa&#xff1a;A Robustly Optimized BERT Pretraining Approach 作者&#xff1a;Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar Joshi, Da…

【Qt5】Q_UNUSED()

2023年12月9日&#xff0c;周六晚上 Q_UNUSED()是一個用于告訴編譯器不使用&#xff08;或者未使用&#xff09;特定變量的宏。 有時候&#xff0c;在函數簽名中聲明了某些參數&#xff0c;但是在函數體內并沒有使用它們。這可能是因為在某些情況下&#xff0c;函數可能需要接…