Golang異常處理機制

?go語言使用error來處理錯誤,用panic和recover來處理異常

error

go語言的錯誤處理有兩個發展階段,以go1.13版本為分水嶺,在1.13版本之前,標準庫對error的支持非常有限,僅有errors.New()和fmt.Errorf()兩個函數來構造errorString實例。在這個階段,error處理存在一個非常大的問題:傳遞錯誤時,使用fmt.Errorf()傳遞捕獲的error并為error增加上下文信息時,原error將和上下文的描述信息混雜在一起,導致原始的error信息丟失。

在go1.13版本,Go官方加強了對errors的支持,在進行錯誤傳遞的時候,采用鏈式傳遞的方式,將同一上下文的error鏈接起來,并且保留原始的error信息。通過在fmt.Errorf()中增加一個格式動詞%w,來創建鏈式的error,并且提供errors.Unwarp()來拆解error。

創建錯誤的兩種方式:

  1. errors.New(str string)

  2. fmt.Errorf("format string",a ...any)

我們可以通過以上兩種方式來創建錯誤類型,第一種創建出來的是stringError,第二種方式創建出來的類型,取決于傳入的格式動詞,在1.13版本之前只能夠創建stringError類型的錯誤。在1.13版本之后,通過傳入格式動詞%w,可以創建出warpError類型的錯誤,我們需要注意的是,傳入的%w應該和傳入的err來配對。

defer

不僅函數正常返回會執行被defer延遲的函數,函數中任意一個return語句、panic語句均會觸發延遲函數。

defer的三大規則:

  1. 延遲函數的參數在defer語句出現時就已經確定了,延遲函數體中引用的變量,在編譯的會綁定主函數中的對應變量,會獲取變量的最終值。【對于指針函數的變量,復制的是地址值】

  2. 延遲函數按后進先出的順序執行,即先出現的defer最后執行

  3. 延遲函數可能會操作主函數的具名返回值。【return的返回操作并不是原子性的,而是分為兩個步驟:一是設置返回值,二是執行跳轉,defer語句發生在跳轉之前】(分析方向,先判斷返回值的類型,是匿名還是具名,只有在defer語句中,對具名返回值進行更改的時候,才會修改返回值)

panic

panic的工作機制:每一個協程中都維護一個defer鏈表,執行過程中每遇到一個defer語句都會創建一個defer實例,并將這一個defer實例插入鏈表,函數退出時取出本函數創建的defer實例并執行。panic發生時,實際上是把程序的流程轉向了這一個defer鏈表,程序專注于消費鏈表中的defer函數,當鏈表中的defer函數被消費完,再觸發程序的退出。

我們在程序中一些可以預料到的、業務上的錯誤,可以通過定義err進行異常處理,處理err時,我們的程序是正常的,按照我們編寫的邏輯順序執行的。 而panic則用來處理不可預料到的錯誤和進行危險操作時觸發panic。一旦程序發生panic,那么panic所在的函數體之后的代碼將不會再執行,轉而遞歸執行當前協程所有的defer函數,當前協程中的所有defer處理完成后,觸發程序退出。如果panic執行過程中任意一個defer函數執行了recover(),那么panic的處理流程就會中止。程序繼續執行上游函數中的代碼。

recover

內置函數recover()用于消除panic并使程序回到正常的執行流程中。

recover的返回值是捕獲到的panic()函數的參數

recover()執行之后,程序的執行流程轉向上游函數,并且上游函數感知不到panic的發生。而發生panic的函數后面的代碼不會被執行。【一旦發生驚慌,函數的執行流程就變了】

recover()函數必須直接位于defer函數中才有效。defer func() { recover() }()

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

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

相關文章

javaweb中的請求與響應--基于postman工具的應用(附帶postman的詳細安裝步驟)

一、前言 后端的第一天感覺難度就上來了,可能是基礎太過薄弱了吧。目前看視頻已經有點跟不上了,果然15天想要拿下還是太勉強了點。30天還差不多。不知道讀者們有沒有好好的去學這方面的知識,沒有什么是學不會的,關鍵是堅持。 Po…

幾個小創新模型,KAN組合網絡(LSTM、GRU、Transformer)回歸預測,python預測全家桶再更新!...

截止到本期,一共發了9篇關于機器學習預測全家桶Python代碼的文章。參考往期文章如下: 1.終于來了!python機器學習預測全家桶 2.機器學習預測全家桶-Python,一次性搞定多/單特征輸入,多/單步預測!最強模板&a…

蘿卜快跑的狠活

蘿卜快跑作為百度旗下的自動駕駛出行服務平臺,在科技應用上展現了多項領先的技術。以下是蘿卜快跑采用的一些主要科技“狠活”: 自動駕駛技術: 蘿卜快跑主要使用了百度Apollo的L4級自動駕駛技術,該技術能夠應對海量的城市道路場景…

C++:重定義

派生類和基類的同名成員問題 派生類中再實現一個基類中的方法會怎樣 (1)代碼實驗:派生類和基類中各自實現一個內容不同但函數原型完全相同的方法,會怎么樣 (2)結論:基類對象調用的是基類的方法,派生類對象調用執行的是派生類中重…

進程調度篇

在操作系統的廣闊領域中,進程調度是其中一個至關重要的環節。它如同操作系統的“交通警察”,負責在多個等待CPU執行的進程間進行高效、公平的分配。本文將帶您了解進程調度的基本概念、重要性、常用算法…… 1. 進程調度的基本概念 1.1 進程調度的定義 …

【FreeRTOS】freeRTOS的Tmr Svc任務優先級配置

1、Tmr Svc是個FreeRTOS的軟件定時器任務,他可以收集各任務的狀態 2、他的優先級可以通過宏 configTIMER_TASK_PRIORITY 來配置,默認是2 3、修改為31后,程序總是啟動不了, 4、后面才發現原來FreeRTOS的默認最大優先級號配置的是…

工具指南 - jenkins

一、接入SonarQube 掃描代碼 SonarQube是一個用于管理代碼質量的開放平臺,可以快速的定位代碼中潛在的或者明顯的錯誤。 1.1 源碼管理 如果源碼托管在SVN,需要進行Subversion配置: Repository URL:源碼地址,比如https:…

一鍵優雅為Ubuntu20.04服務器掛載新磁盤

itopen組織1、提供OpenHarmony優雅實用的小工具2、手把手適配riscv qemu linux的三方庫移植3、未來計劃riscv qemu ohos的三方庫移植 小程序開發4、一切擁抱開源,擁抱國產化 一、小于2T磁盤掛載方式 1.1 安裝磁盤到電腦后啟動系統 1.2 查找未分區的磁盤 打…

ios swift5 藍牙廣播出數據

WARNING: The advertisement key ‘Manufacturer Data’ is not allowed WARNING: The advertisement key ‘Service Data’ is not allowed manager?.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [myService?.uuid], CBAdvertisementDataLocalNameKey : "…

鴻蒙Navigation的頁面跳轉官方代碼

星河版本 文章部分代碼來源于官方 文章部分代碼來源于官方只是自己改了容易理解 與API4不同的Navigation 新版本使用的思路是 1、創建頁面棧 pageInfos: NavPathStack new NavPathStack();2、resources/base/profile創建 router_map.json 文件 {"routerMap":…

數電設計提問求幫助,出租車計費器。

🏆本文收錄于《CSDN問答解惑-》專欄,主要記錄項目實戰過程中的Bug之前因后果及提供真實有效的解決方案,希望能夠助你一臂之力,幫你早日登頂實現財富自由🚀;同時,歡迎大家關注&&收藏&…

Autosar診斷實戰系列28-2E寫DID Pending期間偶發回NRC0x13問題排查

本文框架 前言1.問題描述2.問題復現3.問題分析問題1:為何在2E Pending期間會發送功能尋址的10 01回NRC13?問題2:在ECU Pending期間收到功能尋址10 01,MCU需要如何處理?問題3:DcmDslConnection是如何定義的?問題4:功能尋址于物理尋址是否對應不同的DcmDslConnection?問…

Pandas數據可視化寶典:解鎖圖形繪制與樣式自定義的奧秘

Pandas數據可視化寶典:解鎖圖形繪制與樣式自定義的奧秘 引言 數據可視化是將數據以圖形或圖像的形式展示出來,使復雜的數據更容易被人類理解和分析。在數據分析、商業智能、科學研究等領域,數據可視化都扮演著至關重要的角色。Pandas作為一…

如何通過 Java 來完成 zip 文件與 rar 文件的解壓縮?

目錄 一、用到的知識點 二、代碼展示(分解版) 三、代碼展示(整體版) 一、用到的知識點 1.IO流: Input:輸入,通過“輸入流”進行文件的讀取操作 Output:輸出,通過“輸出流”進行文件的寫入操作 2.文件操作相關: File類&#xff…

Point Cloud Library (PCL) for Python - pclpy 安裝指南 (2)

Point Cloud Library (PCL) for Python - pclpy 安裝指南 (1) 導入庫 from pclpy import pcl import numpy as np導入pclpy庫中的pcl模塊,用于處理點云數據。numpy庫用于處理數值數據。 讀取點云 cloud pcl.PointCloud.PointXYZRGB() pcl.io.loadPCDFile(F:\\bunn…

2024年西安鐵一中集訓DAY1---- 雜題選講

文章目錄 牛客練習賽125 E 聯誼活動(枚舉,分討)牛客練習賽125 F 玻璃彈珠(類莫隊,離線詢問,數據結構)2024ccpc長春邀請賽 D Parallel Lines(隨機化)2024ccpc長春邀請賽 E…

STM32智能健康監測系統教程

目錄 引言環境準備智能健康監測系統基礎代碼實現:實現智能健康監測系統 4.1 數據采集模塊 4.2 數據處理與分析模塊 4.3 通信與網絡系統實現 4.4 用戶界面與數據可視化應用場景:健康監測與優化問題解決方案與優化收尾與總結 1. 引言 智能健康監測系統通…

k8s 容器環境下的鏡像如何轉換為docker 使用

在無法連接registry 的環境中,想要把 crictl 中的鏡像給docker 使用,應該怎么處理? 其實容器鏡像是通用的,crictl 和ctr 以及docker 鏡像是可以互相使用的,因為docker 在1.10版本之后遵從了OCI。所以crictl 環境下的鏡…

Android Studio 的Gradle下載慢,Gradle切換下載源

看圖 下面的文字地址因為轉義符號的問題,https后面少了一個斜杠看圖片進行補充,直接復制不知道能不能用 distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-8.7-bin.zip

浪潮服務器內存物理插槽位置

浪潮服務器內存物理插槽位置 如下圖所示