Golang error使用場(chǎng)景介紹
前言
在Go的編程中, error的使用場(chǎng)景數(shù)不勝數(shù), 主要就是用來(lái)處理各種異常情況.
長(zhǎng)久以來(lái), 我的使用方式都是這樣的:
err := errors.New("fail")
if err != nil{
//do somethine...
}
簡(jiǎn)單易懂.
但是, 如果我們的調(diào)用鏈?zhǔn)沁@樣的func1 -> func2 -> func3 -> func4 -> func5, 此時(shí)func5發(fā)生錯(cuò)誤, error逐層向上傳遞, func1拿到錯(cuò)誤后, 因?yàn)槿鄙俣褩P畔? 很難根據(jù)error還原出錯(cuò)場(chǎng)景.
那么, 根據(jù)這個(gè)問(wèn)題, 又該如何處理呢? 很簡(jiǎn)單, 函數(shù)拿到error后, 在其中添加當(dāng)前上下文信息后再返回不就行了么? 類(lèi)似于這樣:
func func4() error {
err := func5()
if err != nil {
return errors.New(err.Error() + "--func4")
}
return nil
}
這當(dāng)然可以. 但是上層還可能根據(jù)不同的error進(jìn)行不同的異常處理, 這樣的話, 使用err == SameErr的判斷條件就不好使了.
那么, 如何能夠在error中添加信息的同時(shí), 又不丟失原始error的信息呢?
其實(shí), 官方已經(jīng)做好了類(lèi)似的支持.
error
在Go的fmt庫(kù)中有這樣一個(gè)error:
type wrapError struct {
msg string
err error
}
func (e *wrapError) Error() string {
return e.msg
}
func (e *wrapError) Unwrap() error {
return e.err
}
它提供了一個(gè)Error方法來(lái)實(shí)現(xiàn)error接口, 同時(shí)還會(huì)保存原始的err信息, 可以通過(guò)Unwrap獲得. 這不就是我們需要得么?
官方對(duì)其的使用進(jìn)行了封裝, 包含了:
- 對(duì)異常進(jìn)行包裝
- 判斷指定異常是否存在與包裝鏈中
- 從包裝鏈中提取指定類(lèi)型的異常
// 對(duì) err 進(jìn)行包裝.
// 注意, 占位符必須為 %w, 否則返回的就是一個(gè)普通 error
err1 := fmt.Errorf("func4: %w", err)
// 判斷 err1 中是否包含 SameErr 這個(gè)錯(cuò)誤
// 相當(dāng)于對(duì)所有 error 依次解包并進(jìn)行 == 的比較
if errors.Is(err1, SameErr) {
// 存在 SameErr
}
// 從 err 中獲取指定類(lèi)型的錯(cuò)誤
var sameErr *SameErrStruct
if errors.As(err, &sameErr) {
// 成功從 err 中獲取到 SameErr
}
// 對(duì)error 進(jìn)行解包, 若失敗返回 nil
retErr := errors.Unwrap(err1)
翻了翻幾個(gè)方法的源碼都比較簡(jiǎn)單, 在這里就不細(xì)述了.
調(diào)用棧
但是, 這樣一層一層將調(diào)用信息返回去, 還是有些麻煩, 有沒(méi)有什么辦法, 能夠直接將調(diào)用棧放進(jìn)去呢? 或者說(shuō), 在Go中如何獲取調(diào)用棧呢?
func getStack() {
// 獲取當(dāng)前調(diào)用棧
pcs := make([]uintptr, 64)
pcNum := runtime.Callers(2, pcs) // skip 2 是為了跳過(guò) Callers 及其內(nèi)部函數(shù)
// 調(diào)用棧解析
frames := runtime.CallersFrames(pcs[:pcNum])
for frame, more := frames.Next(); more; frame, more = frames.Next() {
fmt.Printf("file: %s, line: %d, func: %s\n", frame.File, frame.Line, frame.Function)
}
}
OK, 所謂大道至簡(jiǎn), error也就這么點(diǎn)東西, 完全能夠滿(mǎn)足使用了. 再見(jiàn)
到此這篇關(guān)于Golang error使用場(chǎng)景介紹的文章就介紹到這了,更多相關(guān)Go error內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言實(shí)現(xiàn)websocket推送程序
這篇文章主要介紹了Go語(yǔ)言實(shí)現(xiàn)websocket推送程序,WebSocket是基于TCP的一個(gè)雙向傳輸數(shù)據(jù)的協(xié)議,和HTTP協(xié)議一樣,是在應(yīng)用層的,他的出現(xiàn),是為了解決網(wǎng)頁(yè)進(jìn)行持久雙向傳輸數(shù)據(jù)的問(wèn)題2023-01-01
利用GO語(yǔ)言實(shí)現(xiàn)多人聊天室實(shí)例教程
聊天室的實(shí)現(xiàn)大家應(yīng)該都遇到過(guò),這篇文章主要給大家介紹了關(guān)于利用GO語(yǔ)言實(shí)現(xiàn)多人聊天室的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2018-03-03
分析Go錯(cuò)誤處理優(yōu)化go?recover機(jī)制缺陷
這篇文章主要為大家介紹了分析Go錯(cuò)誤處理優(yōu)化go?recover機(jī)制缺陷示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Go 使用Unmarshal將json賦給struct出錯(cuò)的原因及解決
這篇文章主要介紹了Go 使用Unmarshal將json賦給struct出錯(cuò)的原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
Go語(yǔ)言實(shí)現(xiàn)JSON解析的神器詳解
php轉(zhuǎn)go是大趨勢(shì),越來(lái)越多公司的php服務(wù)都在用go進(jìn)行重構(gòu),重構(gòu)過(guò)程中,會(huì)發(fā)現(xiàn)php的json解析操作是真的香。本文和大家分享了一個(gè)Go語(yǔ)言實(shí)現(xiàn)JSON解析的神器,希望對(duì)大家有所幫助2023-01-01
一文帶你吃透Golang中net/http標(biāo)準(zhǔn)庫(kù)服務(wù)端
這篇文章將從服務(wù)端(Server)作為切入點(diǎn)和大家分享一下Go語(yǔ)言net/http標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)邏輯,進(jìn)而一步步分析http標(biāo)準(zhǔn)庫(kù)內(nèi)部是如何運(yùn)作的,感興趣的可以了解下2024-03-03
詳解golang開(kāi)發(fā)中http請(qǐng)求redirect的問(wèn)題
這篇文章主要介紹了詳解golang開(kāi)發(fā)中http請(qǐng)求redirect的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10

