GO語言學習筆記(與Java的比較學習)(十)

錯誤處理與測試

Go 沒有像 Java 和 .NET 那樣的 try/catch 異常機制:不能執行拋異常操作。但是有一套 defer-panic-and-recover 機制

錯誤處理

Go 有一個預先定義的 error 接口類型

type error interface {Error() string
}

errors 包中有一個 errorString 結構體實現了 error 接口。當程序處于錯誤狀態時可以用 os.Exit(1) 來中止運行。

定義錯誤

任何時候當你需要一個新的錯誤類型,都可以用 errors(必須先 import)包的 errors.New 函數接收合適的錯誤信息來創建,像下面這樣:

err := errors.New(“math - square root of negative number”)

包也可以用額外的方法(methods)定義特定的錯誤,比如 net.Error:

package net
type Error interface {Timeout() bool ? // Is the error a timeout?Temporary() bool // Is the error temporary?
}

用 fmt 創建錯誤對象

通常你想要返回包含錯誤參數的更有信息量的字符串,例如:可以用 fmt.Errorf() 來實現:它和 fmt.Printf () 完全一樣,接收有一個或多個格式占位符的格式化字符串和相應數量的占位變量。和打印信息不同的是它用信息生成錯誤對象。

比如在前面的平方根例子中使用:

if f < 0 {return 0, fmt.Errorf("math: square root of negative number %g", f)
}

運行時異常和 panic

當發生像數組下標越界或類型斷言失敗這樣的運行錯誤時,Go 運行時會觸發運行時 panic,伴隨著程序的崩潰拋出一個 runtime.Error 接口類型的值。這個錯誤值有個 RuntimeError() 方法用于區別普通錯誤。

panic 可以直接從代碼初始化:當錯誤條件(我們所測試的代碼)很嚴苛且不可恢復,程序不能繼續運行時,可以使用 panic 函數產生一個中止程序的運行時錯誤。panic 接收一個做任意類型的參數,通常是字符串,在程序死亡時被打印出來。Go 運行時負責中止程序并給出調試信息。

package main
?
import "fmt"
?
func main() {fmt.Println("Starting the program")panic("A severe error occurred: stopping the program!")fmt.Println("Ending the program")
}

從 panic 中恢復(Recover)

正如名字一樣,這個(recover)內建函數被用于從 panic 或 錯誤場景中恢復:讓程序可以從 panicking 重新獲得控制權,停止終止過程進而恢復正常執行。

recover 只能在 defer 修飾的函數中使用:用于取得 panic 調用中傳遞過來的錯誤值,如果是正常執行,調用 recover 會返回 nil,且沒有其它效果。

總結:panic 會導致棧被展開直到 defer 修飾的 recover () 被調用或者程序中止

這跟 Java 和 .NET 這樣的語言中的 catch 塊類似。 log 包實現了簡單的日志功能:默認的 log 對象向標準錯誤輸出中寫入并打印每條日志信息的日期和時間。除了 Println 和 Printf 函數,其它的致命性函數都會在寫完日志信息后調用 os.Exit (1),那些退出函數也是如此。而 Panic 效果的函數會在寫完日志信息后調用 panic;可以在程序必須中止或發生了臨界錯誤時使用它們,就像當 web 服務器不能啟動時那樣

自定義包中的錯誤處理和 panicking

這是所有自定義包實現者應該遵守的最佳實踐:

1)在包內部,總是應該從 panic 中 recover:不允許顯式的超出包范圍的 panic ()

2)向包的調用者返回錯誤值(而不是 panic)。

啟動外部命令和程序

os 包有一個 StartProcess 函數可以調用或啟動外部系統命令和二進制可執行文件;它的第一個參數是要運行的進程,第二個參數用來傳遞選項或參數,第三個參數是含有系統環境基本信息的結構體。

這個函數返回被啟動進程的 id(pid),或者啟動失敗返回錯誤

Go 中的單元測試和基準測試

_test 程序不會被普通的 Go 編譯器編譯,所以當放應用部署到生產環境時它們不會被部署;只有 gotest 會編譯所有的程序:普通程序和測試程序。

測試文件中必須導入 "testing" 包,并寫一些名字以 TestZzz 打頭的全局函數,這里的 Zzz 是被測試函數的字母描述,如 TestFmtInterface,TestPayEmployees 等。

測試的編寫規則:

Go 的測試必須按規則方式編寫,不然 go test 將無法正確定位測試代碼的位置,主要三點規則。

首先,測試代碼文件的命名必須是以 _test.go 結尾,比如上節中的文件名 math_tesh.go 并非隨意取的。

還有,代碼中的用例函數必須滿足匹配 TestXxx,比如 TestAbs。

關于 Xxx,簡單解釋一下,它主要傳達兩點含義,一是 Xxx 表示首個字符必須大寫或數字,簡單而言就是可確定單詞分隔,二是首字母后的字符可以是任意 Go 關鍵詞合法字符,如大小寫字母、下劃線、數字。

測試函數必須有這種形式的頭部:

func TestAbcde(t *testing.T)

T 是傳給測試函數的結構類型,用來管理測試狀態,支持格式化測試日志,如 t.Log,t.Error,t.ErrorF 等。在函數的結尾把輸出跟想要的結果對比,如果不等就打印一個錯誤。成功的測試則直接返回。

用下面這些函數來通知測試失敗:

1)func (t *T) Fail()

標記測試函數為失敗,然后繼續執行(剩下的測試)。

2)func (t *T) FailNow()

標記測試函數為失敗并中止執行;文件中別的測試也被略過,繼續執行下一個文件。

3)func (t *T) Log(args ...interface{})

args 被用默認的格式格式化并打印到錯誤日志中。

4)func (t *T) Fatal(args ...interface{})

結合 先執行 3),然后執行 2)的效果。
package even
?
import "testing"
?
func TestEven(t *testing.T) {if !Even(10) {t.Log(" 10 must be even!")t.Fail()}if Even(7) {t.Log(" 7 is not even!")t.Fail()}
?
}
?
func TestOdd(t *testing.T) {if !Odd(11) {t.Log(" 11 must be odd!")t.Fail()}if Odd(10) {t.Log(" 10 is not odd!")t.Fail()}
}

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

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

相關文章

十二、類與聲明

類與聲明 什么是類&#xff1f; 前情總結 前面22講的課基本上就做了兩件事 學習C#的基本元素學習類的成員 析構函數&#xff1a; 當對象不再被引用的時候&#xff0c;就會被垃圾回收器gc&#xff0c;回收。而收回的過程當中&#xff0c;如果需要做什么事情&#xff0c;就放在…

遠程調用--Http Interface

遠程調用--Http Interface 前言1、導入依賴2、定義接口3 創建代理&測試4、創建成配置變量 前言 這個功能是spring boot6提供的新功能&#xff0c;spring允許我們通過自定義接口的方式&#xff0c;給任意位置發送http請求&#xff0c;實現遠程調用&#xff0c;可以用來簡化…

已解決org.springframework.dao.DataRetrievalFailureException數據檢索失敗異常的正確解決方法,親測有效!!!

已解決org.springframework.dao.DataRetrievalFailureException數據檢索失敗異常的正確解決方法&#xff0c;親測有效&#xff01;&#xff01;&#xff01; 目錄 問題分析 出現問題的場景 報錯原因 解決思路 解決方法 總結 在使用Spring Framework進行數據庫操作時&…

關于硅金屬電阻器?

EAK金屬硅電阻器類似于陶瓷復合電阻器&#xff0c;在脈沖負載方面具有優勢&#xff0c;需要高峰值功率或高電壓與低電感&#xff08;如預充電電路&#xff09;的組合。硅金屬電阻器具有更高的連續額定溫度&#xff0c;為 350C&#xff0c;而陶瓷電阻器為 250C。這種擴展的溫度范…

[藍橋杯 2023 省 B] 冶煉金屬

P9240 [藍橋杯 2023 省 B] 冶煉金屬 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) 參考題解&#xff1a; #C3150——藍橋杯2023年第十四屆省賽真題-冶煉金屬(分塊)-Dotcpp編程社區 https://www.bilibili.com/video/BV1wc411x7KU/?spm_id_from333.1007.top_right_bar_windo…

RT-Thread操作系統 串口DMA接收時數據被拆分多包

一、問題現象 在使用RT Thread操作系統&#xff0c;串口DMA接收數據時&#xff0c;通過log打印發現&#xff0c;例如GPS NEMA數據一包數據量較大或者時&#xff0c;接收到的數據被拆分多包處理&#xff1b; 二、問題解決方案 修改DMA驅動程序 在drivers/drv_usart.c中屏蔽如…

板子合集1.0

版權聲明&#xff1a;本文為博主原創文章&#xff0c;遵循 CC 4.0 BY-SA 版權協議&#xff0c;轉載請附上原文出處鏈接和本聲明。 原文鏈接&#xff1a;https://blog.csdn.net/JK01WYX/ 文章目錄 1.快速冪板子2.gcd得最大公約數3.堆優化的dijkstra板子4.線段樹1板子 區間加線段…

中綴表達式轉換逆波蘭式(后綴表達式)

算法思路來自于王道的數據結構 #include <iostream> #include <stack> #include <map>using namespace std; string eq; stack<char> op; string rst ""; map<char, int> dict;// 獲取優先級 int getPrio(char op) {if (op )return …

【Dubbo專欄 01 】深入探索:dubbo的架構是什么?

文章目錄 Dubbo&#xff1a;深入解析分布式服務框架的核心概念與實現01 Dubbo簡介02 Dubbo核心概念2.1 服務提供者&#xff08;Provider&#xff09;2.2 服務消費者&#xff08;Consumer&#xff09;2.3 注冊中心&#xff08;Registry&#xff09;2.4 負載均衡&#xff08;Load…

如何對用OpenCV開發的API進行測試 (Google Test 版本)

如何對用OpenCV開發的API進行測試 &#xff08;Google Test 版本&#xff09; 如何對用OpenCV開發的API進行測試斷言介紹斷言基礎的斷言數值比較字符串比較 如何對用OpenCV開發的API進行測試 假設你想測試一個使用OpenCV開發的圖像處理API&#xff0c;例如一個圖像濾波函數。以…

SWC Runnable

runnable概念 runnable是編寫應用程序行為邏輯的 SWC 的一部分。Runnable 類似于 C 中的函數,類似RTOS中的task,程序運行的實體,swc的靈魂。在 AUTOSAR 中,我們在配置期間在 SWC 中創建 Runnable,并且 在 SWC 的相應源文件中生成Runnable 或函數骨架。骨架函數的名稱與我…

【硬件工程師面經整理15_低通/高通/帶通濾波器】

低通/高通/帶通濾波器 1.1 低通濾波器1.2 高通濾波器1.3 帶通濾波器 1.1 低通濾波器 【定義】電感阻止高頻信號通過而允許低頻信號通過&#xff0c;電容的特性卻相反。信號能夠通過電感的濾波器、或者通過電容連接到地的濾波器對于低頻信號的衰減要比高頻信號小&#xff0c;稱…

第二篇【傳奇開心果系列】Python的自動化辦公庫技術點案例示例:深度解讀Pandas金融數據分析

傳奇開心果博文系列 系列博文目錄Python的自動化辦公庫技術點案例示例系列 博文目錄前言一、Pandas 在金融數據分析中的常見用途和功能介紹二、金融數據清洗和準備示例代碼三、金融數據索引和選擇示例代碼四、金融數據時間序列分析示例代碼五、金融數據可視化示例代碼六、金融數…

軟考高級:DNS欺騙相關知識和例題

一、AI 解析 DNS欺騙&#xff0c;又稱DNS緩存投毒&#xff0c;是一種網絡攻擊技術。攻擊者通過篡改DNS服務器的緩存數據&#xff0c;使得DNS查詢的結果指向一個惡意的IP地址&#xff0c;從而引導用戶訪問到釣魚網站或者惡意軟件下載頁面&#xff0c;對用戶的信息安全造成威脅。…

后臺組件-IO定義

<groupId>org.qlm</groupId><artifactId>qlm-io</artifactId><version>1.0-SNAPSHOT</version> 該組件定義了前端和后臺微服務直接通訊結構以及返回值定義。 RequestInfo&#xff1a;請求結構 ResponseResult&#xff1a;非分頁的返回結…

最新版風車IM通訊iosapph5三端源碼及視頻教程

最新版風車IM通訊iosapph5三端源碼及視頻教程 1.寶塔環境如下: Nginx 1.20 Tomcat 8 MySQL 8.0 Redis 7 2.放行端口如下&#xff1a; 666 6600 6700 7000&#xff08;用作前端&#xff09; 7001&#xff08;用作后端&#xff09; 3.寶塔數據庫添加數據庫旁邊有個ro…

Sqli-labs靶場第21、22關詳解[Sqli-labs-less-21、22]自動化注入-SQLmap工具注入|sqlmap跑base64加密

Sqli-labs-Less-21、22 由于21/22雷同&#xff0c;都是需要登錄后&#xff0c;注入點通過Cookie值進行測試&#xff0c;值base64加密 修改注入數據 選項&#xff1a;--tamperbase64encode #自動化注入-SQLmap工具注入 SQLmap用戶手冊&#xff1a;文檔介紹 - sqlmap 用戶手冊 由…

MySql行子查詢

目錄 行子查詢數據準備 行子查詢 子查詢返回的結果是一行(可以是多列)&#xff0c;這種子查詢稱為行子查詢。 常用的操作符&#xff1a; 、<> 、IN 、NOT IN 案例&#xff1a;查詢與"韋一笑"的入職日期及職位都相同的員工信息 可以拆解為兩步進行&#xff1…

框架漏洞-->Struts2 Docker_Vulnhub搭建

來淺淺的講一下Struts2漏洞 目錄 1.Docker_Vulnhub搭建 2.Struts2 3.Struts2的框架特征 4.S2-029-->Remote Code Execution 5.漏洞復現 1.RCE 2.Getshell 1.Docker_Vulnhub搭建 因為我用的是Linux&#xff0c;所以我選擇直接搭個docker&#xff0c;這里我建議先換個…

在Ubuntu22.04安裝Fcitx5中文輸入法教程(十分詳細)

前言 書接上回&#xff0c;一時興起將主力機的 Ubuntu 20.04 LTS 升級至了剛剛發布的 22.04 LTS。從 X 切換到 Wayland 、GNOME 從 3.36 升級至 42、Python 默認為 3.10 等等……使用太新的軟件包反而暫時帶來了麻煩&#xff0c;部分原有的軟件和插件都不可用了。這其中就包括…