Golang通常有三種錯誤處理方式:錯誤哨兵(Sentinel Error)、錯誤類型斷言和記錄錯誤呼叫堆疊。錯誤哨兵指的是用特定值的變數作為錯誤處理分支的判定條件。錯誤類型用於路由錯誤處理邏輯,和錯誤哨兵有異曲同工的作用,由類型系統來提供錯誤種類的唯一性。錯誤黑盒指的是不過度關心錯誤類型,將錯誤傳回給上層;當需要採取行動時,要針對錯誤的行為進行斷言,而非錯誤類型。
本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。
golang沒有提供try-catch
類似的錯誤處理機制,在設計層面採用了C語言風格的錯誤處理,透過函數傳回值傳回出錯的錯誤訊息,具體樣例如下:
func ReturnError() (string, error) { return "", fmt.Errorf("Test Error") } func main() { val, err := ReturnError() if err != nil { panic(err) } fmt.Println(val) }
上面的例子是一個基本的錯誤處理樣例,生產環境中執行的調用棧往往非常複雜,返回的error
也各式各樣,常常需要根據返回的錯誤訊息確定具體的錯誤處理邏輯。
Golang通常有以下的三種錯誤處理方式,錯誤哨兵(Sentinel Error)、錯誤類型斷言(Error Type Asseration)和記錄錯誤呼叫堆疊。
錯誤哨兵(Sentinel Error)
哨兵指的是用特定值的變數作為錯誤處理分支的判定條件,常見的應用場景有gorm中的gorm.RecordNotFounded
和redis庫裡的redis.NIL
。
golang裡可以對同類型變數進行比較,介面變數則比較介面指向的的指標的位址。因此,當且僅當error
類型的變數指向相同位址時,此兩個變數相等,否則皆為不相等。
var ErrTest = errors.New("Test Error") err := doSomething() if err == ErrTest{ // TODO: Do With Error }
使用哨兵存在以下幾個問題有兩個問題:
1、程式碼結構不靈活,分支處理只能使用==
或! =
進行判定,長此以往,容易寫出常義大利麵式的程式碼。
var ErrTest1 = errors.New("ErrTest1") var ErrTest2 = errors.New("ErrTest1") var ErrTest3 = errors.New("ErrTest1") …… var ErrTestN = errors.New("ErrTestN") …… if err == ErrTest1{ …… } else if err == ErrTest2{ …… }else if err == ErrTest3{ …… } …… else err == ErrTestN{ …… }
2、哨兵變數值不能被修改,否則會導致邏輯錯誤,上述golang寫法的error哨兵可以被改變,可以透過以下方式解決:
type Error string func (e Error) Error() string { return string(e) }
3、哨兵變數會導致極強的耦合性,介面新增error的吐出就會造成使用者對應修改程式碼新增處理錯誤的問題。
比較上面的方案,錯誤哨兵還有一個更優雅的方案,依賴介面而非變數:
var ErrTest1 = errors.New("ErrTest1") func IsErrTest1(err error) bool{ return err == ErrTest1 }
錯誤類型
#錯誤類型來路由錯誤處理邏輯,和錯誤哨兵有異曲同工的作用,由類型系統來提供錯誤種類的唯一性,使用方法如下:
type TestError { } func(err *TestError) Error() string{ return "Test Error" } if err, ok := err.(TestError); ok { //TODO 错误分支处理 } err := something() switch err := err.(type) { case nil: // call succeeded, nothing to do case *TestError: fmt.Println("error occurred on line:", err.Line) default: // unknown error }
相比較於哨兵,錯誤類型的不變性更好,而且可以使用switch
來提供優雅的路由策略。但這使得使用方依舊無法避免對於套件的過重依賴。
使用介面拋出更複雜,多樣的錯誤,依舊需要改變呼叫方的程式碼。
錯誤黑盒(依賴錯誤介面)
錯誤黑盒指的是不過度關心錯誤類型,將錯誤傳回給上層。當需要採取行動時,要針對錯誤的行為進行斷言,而非錯誤類型。
func fn() error{ x, err := Foo() if err != nil { return err } } func main(){ err := fn() if IsTemporary(err){ fmt.Println("Temporary Error") } } type temporary interface { Temporary() bool } // IsTemporary returns true if err is temporary. func IsTemporary(err error) bool { te, ok := err.(temporary) return ok && te.Temporary() }
透過這樣的方式,1.直接就解耦了介面間的依賴,2. 錯誤處理路由和錯誤類型無關,而與具體行為有關,避免了膨脹的錯誤類型。
總結
錯誤哨兵和錯誤類型避免不了依賴過重的問題,只有錯誤黑盒能夠將問題從確定錯誤類型(變數)的處理邏輯變為確定錯誤行為。因此建議使用第三種方式來處理錯誤。
這裡必要要加一句,黑盒處理,返回錯誤並不意味著對錯誤的存在不理會或者是直接忽略,而是需要在合適的地方優雅得處理。在這個過程中,可以透過errors的Wrap
,Zap打log等方式,在錯誤逐層傳回的過程中記錄呼叫連結的上下文訊息。
func authenticate() error{ return fmt.Errorf("authenticate") } func AuthenticateRequest() error { err := authenticate() // OR logger.Info("authenticate fail %v", err) if err != nil { return errors.Wrap(err, "AuthenticateRequest") } return nil } func main(){ err := AuthenticateRequest() fmt.Printf("%+v\n", err) fmt.Println("##########") fmt.Printf("%v\n", errors.Cause(err)) } // 打印信息 authenticate AuthenticateRequest main.AuthenticateRequest /Users/hekangle/MyPersonProject/go-pattern/main.go:17 main.main /Users/hekangle/MyPersonProject/go-pattern/main.go:23 runtime.main /usr/local/Cellar/go@1.13/1.13.12/libexec/src/runtime/proc.go:203 runtime.goexit /usr/local/Cellar/go@1.13/1.13.12/libexec/src/runtime/asm_amd64.s:1357 ########## authenticate
以上是golang怎麼進行錯誤處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

在PHP语言开发中,请求头错误通常是由于HTTP请求中的一些问题导致的。这些问题可能包括无效的请求头、缺失的请求体以及无法识别的编码格式等。而正确处理这些请求头错误是保证应用程序稳定性和安全性的关键。在本文中,我们将讨论一些处理PHP请求头错误的最佳实践,帮助您构建更加可靠和安全的应用程序。检查请求方法HTTP协议规定了一组可用的请求方法(例如GET、POS

随着Web应用程序的不断发展,数据交互成为了一个非常重要的环节。其中,JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,广泛用于前后端数据交互。在PHP中,json_encode()函数可以将PHP数组或对象转换为JSON格式字符串,json_decode()函数可以将JSON格式字符串转换为PHP数组或对象。然而,

本文将介绍关于PHP命令行错误的一些你可能不知道的事情。PHP作为一门流行的服务器端语言,一般运行在Web服务器上,但它也可以在命令行上直接运行,比如在Linux或者MacOS系统下,我们可以在终端中输入“php”命令来直接运行PHP脚本。不过,就像在Web服务器中一样,当我们在命令行中运行PHP脚本时,也会遇到一些错误。以下是一些你可能不知道的有关PHP命

在PHP语言开发中,日期格式化错误是一个常见的问题。正确的日期格式对于程序员来说十分重要,因为它决定着代码的可读性、可维护性和正确性。本文将分享一些处理日期格式化错误的技巧。了解日期格式在处理日期格式化错误之前,我们必须先了解日期格式。日期格式是由各种字母和符号组成的字符串,用于表示特定的日期和时间格式。在PHP中,常见的日期格式包括:Y:四位数年份(如20

在编写程序时总会存在各种各样的错误和异常。任何编程语言都需要有良好的容错机制,PHP也不例外。PHP有许多内置的错误和异常处理机制,可以让开发者更好地管理其代码,并正确地处理各种问题。下面就让我们一起来了解一下PHP中的容错机制。错误级别PHP中有四个错误级别:致命错误、严重错误、警告和通知。每个错误级别都有一个不同的符号表示,以帮助识别和处理错误:E_ER

在PHP语言开发中,常常需要解析JSON数据,以便进行后续的数据处理和操作。然而,在解析JSON时,很容易遇到各种错误和问题。本文将介绍常见的错误和处理方法,帮助PHP开发者更好地处理JSON数据。一、JSON格式错误最常见的错误是JSON格式不正确。JSON数据必须符合JSON规范,即数据必须是键值对的集合,并使用大括号({})和中括号([])来包含数据。

随着互联网的快速发展,开发人员的任务也随之多样化和复杂化。特别是对于PHP语言开发人员而言,在开发过程中面临的最常见问题之一就是在开发环境和生产环境中,数据不一致的错误问题。因此,在开发PHP应用程序时,如何处理这些错误是开发人员必须面对的一个重要问题。开发环境和生产环境的区别首先需要明确的是,开发环境和生产环境是不同的,它们有着不同的设置和配置。在开发环境

PHP(HypertextPreprocessor)是一种广泛用于Web开发的脚本语言。在开发PHP应用程序时,错误处理和调试被认为是非常重要的一块。国外程序员在经验中积累了许多PHP错误处理和调试技巧,下面介绍一些比较常见和实用的技巧。错误报告级别修改在PHP中,通过修改错误报告级别可以显示或禁止显示特定类型的PHP错误。通过设置错误报告级别为“E_AL


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver Mac版
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。