基礎(chǔ)
創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司是一家服務(wù)多年做網(wǎng)站建設(shè)策劃設(shè)計(jì)制作的公司,為廣大用戶提供了網(wǎng)站制作、成都做網(wǎng)站,成都網(wǎng)站設(shè)計(jì),1元廣告,成都做網(wǎng)站選創(chuàng)新互聯(lián),貼合企業(yè)需求,高性價(jià)比,滿足客戶不同層次的需求一站式服務(wù)歡迎致電。錯(cuò)誤處理應(yīng)該是工程的一部分,Golang中的error是一個(gè)interface
類型,如下:
type error interface { Error() string }
凡是實(shí)現(xiàn)Error()
方法的結(jié)構(gòu),都可以作為錯(cuò)誤處理。因此如果函數(shù)可能出現(xiàn)錯(cuò)誤,那么可以在返回值的最后,返回一個(gè)錯(cuò)誤,比如:
func foo() error { // ... do something return errors.New("foo error") }
直接返回錯(cuò)誤
直接返回錯(cuò)誤,類似于直接返回字符串類型的錯(cuò)誤,或者錯(cuò)誤碼之類的。字符串類型的錯(cuò)誤,在基礎(chǔ)部分提到了。錯(cuò)誤碼相當(dāng)于Linux、C編程中的錯(cuò)誤碼,一般我們需要自己定義。舉個(gè)例子:
package mypkg type ErrCode int const ( ERR1 = 1 ERR2 = 2 ERR3 = 3 ) func sub(a, b int) (int, ErrCode) { if b < 0 { return 0, ERR1 } else if a < b { return 0, Err2 } else if a < 0 { return 0, Err3 } return a - b }
這種類型的錯(cuò)誤,編寫簡(jiǎn)單,但是有兩個(gè)缺陷:
1、外層如果想要使用錯(cuò)誤碼,則需要引入這個(gè)包,容易出現(xiàn)循環(huán)引用的情況。
2、如果包內(nèi)部修改返回的錯(cuò)誤碼類型,則外部使用到錯(cuò)誤碼的地方,都要進(jìn)行相應(yīng)的修改,破壞了封閉性。
對(duì)于第一個(gè)缺陷,可以使用一個(gè)第三方的包,專門存放錯(cuò)誤碼,這個(gè)方式值得商榷。永遠(yuǎn)不要通過判斷Error()方法返回的字符串的值,來(lái)進(jìn)行對(duì)應(yīng)的錯(cuò)誤處理?。?!
返回自定義類型的錯(cuò)誤
該方式可以返回自定義的類型,并通過斷言自定義類型,來(lái)進(jìn)行有關(guān)的錯(cuò)誤處理;自定義類型可以攜帶更多的信息,代碼實(shí)例:
package main import ( "errors" "fmt" "runtime/debug" ) type MyError struct { Inner error // 內(nèi)粗錯(cuò)誤 Message string // 自定義錯(cuò)誤信息 StackTrace string // 堆棧信息 Misc map[string]interface{} //其它的一些數(shù)據(jù) } func (myError MyError) Error() string { return myError.Message } func wrapError(err error, msg string, msgArgs ...interface{}) MyError { return MyError{ Inner: err, Message: fmt.Sprintf(msg, msgArgs), StackTrace: string(debug.Stack()), Misc: make(map[string]interface{}), } } func Handle(key int) error { if key < 0 { return wrapError(errors.New("key < 0"), "This is an error test") } return nil } func main() { if err := Handle(-1); err != nil { if e, ok := err.(MyError); ok { fmt.Printf("Inner: %v, Message: %v, StackTrace: %v\n", e.Inner, e.Message, e.StackTrace) // 這里輸出對(duì)應(yīng)的數(shù)據(jù) } } }
這種方式處理問題更加方便,但是仍然可能會(huì)有包循環(huán)引用的問題。
隱藏內(nèi)部細(xì)節(jié)的錯(cuò)誤處理
上述兩種方式,可以適應(yīng)一些場(chǎng)景,不過都無(wú)法解決可能存在循環(huán)依賴的問題。為此,我們使用github.com/pkg/errors
的包來(lái)解決問題,給出一個(gè)代碼實(shí)例。
func New(message string) error
如果有一個(gè)現(xiàn)成的error,我們需要對(duì)他進(jìn)行再次包裝處理,這時(shí)候有三個(gè)函數(shù)可以選擇。
//只附加新的信息 func WithMessage(err error, message string) error //只附加調(diào)用堆棧信息 func WithStack(err error) error //同時(shí)附加堆棧和信息 func Wrap(err error, message string) error
其實(shí)上面的包裝,很類似于Java的異常包裝,被包裝的error,其實(shí)就是Cause,在前面的章節(jié)提到錯(cuò)誤的根本原因,就是這個(gè)Cause。所以這個(gè)錯(cuò)誤處理庫(kù)為我們提供了Cause函數(shù)讓我們可以獲得最根本的錯(cuò)誤原因。
func Cause(err error) error { type causer interface { Cause() error } for err != nil { cause, ok := err.(causer) if !ok { break } err = cause.Cause() } return err }
使用for循環(huán)一直找到最根本(最底層)的那個(gè)error。
以上就是關(guān)于golang中的錯(cuò)誤處理機(jī)制的詳細(xì)介紹的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!
網(wǎng)站欄目:go語(yǔ)言中的錯(cuò)誤處理機(jī)制-創(chuàng)新互聯(lián)
文章URL:http://muchs.cn/article22/idpjc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)頁(yè)設(shè)計(jì)公司、動(dòng)態(tài)網(wǎng)站、網(wǎng)站制作、服務(wù)器托管、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容