Go語(yǔ)言中的錯(cuò)誤處理最佳實(shí)踐詳解
錯(cuò)誤處理實(shí)踐
我們?cè)趃o語(yǔ)言中設(shè)計(jì)error的處理體系時(shí)候, 一般都會(huì)去做下面兩點(diǎn)
- 直接使用errors.New()生成error接口的值
- 擴(kuò)展error接口, 并定義擴(kuò)展error接口的實(shí)現(xiàn)類型
error接口是什么
go語(yǔ)言的error是一個(gè)接口類型, 其源碼如下:
type error interface {
Error() string
}我們可以定義它的實(shí)現(xiàn)類型, 比如我們經(jīng)常使用到的errors.New()方法, 返回值為一個(gè)error接口的實(shí)現(xiàn)類型*errorString的結(jié)構(gòu)體字面量
package errors
func New(text string) error {
return &errorString{text}
}
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
//package main
xxxerr := errors.New("xxx")所以我們可以直接調(diào)用errors.New()為我們生成一個(gè)error接口的值
擴(kuò)展的error接口
我們?yōu)槭裁葱枰獙?duì)error接口進(jìn)行擴(kuò)展呢?, 原因是error的實(shí)現(xiàn)類型范圍太大了, 細(xì)粒度不夠小, 所以我們需要實(shí)現(xiàn)更加精細(xì)的控制, 關(guān)于這種設(shè)計(jì)我們可以參考go語(yǔ)言標(biāo)準(zhǔn)庫(kù)中的一些error處理代碼, 比如下面的net.Error
type Error interface {
//嵌入了error接口, 實(shí)現(xiàn)net.Error也會(huì)實(shí)現(xiàn)error
error
//擴(kuò)展
Timeout() bool
Temporary() bool
}然后我們又可以定義一個(gè)類型來(lái)實(shí)現(xiàn)這個(gè)擴(kuò)展錯(cuò)誤接口類型, 比如下面這個(gè)OpError:
type OpError struct {
Op string
Net string
Source Addr
Addr Addr
Err error
}
//實(shí)現(xiàn)函數(shù)1
func (e *OpError) Error() string {
return ""
}
//下面是實(shí)現(xiàn)函數(shù)2
func (e *OpError) Timeout() bool {
//對(duì)應(yīng)的處理邏輯
return true
}
//下面是實(shí)現(xiàn)函數(shù)2
func (e *OpError) Temporary() bool {}我們發(fā)現(xiàn)該結(jié)構(gòu)體中存在一個(gè)名字叫做Err的類型為error的字段, 它代表了該錯(cuò)誤的潛在錯(cuò)誤, 有可能OpError類型的錯(cuò)誤值還包含了AddrError這種錯(cuò)誤
通過(guò)這種類型建立起樹(shù)形的錯(cuò)誤體系, 用統(tǒng)一字段建立可追溯的鏈?zhǔn)藉e(cuò)誤關(guān)聯(lián), 我們就可以建立起來(lái)一套優(yōu)秀的錯(cuò)誤處理機(jī)制
為了更好的表示, 我畫(huà)了一張圖

具體的錯(cuò)誤
因?yàn)镚o語(yǔ)言的error是一個(gè)接口, 所以這個(gè)它的值的實(shí)際類型是非常復(fù)雜的, 于是我們就需要去判斷它的值的一個(gè)實(shí)際類型
- 如果錯(cuò)誤值在某一個(gè)范圍內(nèi), 我們可以使用類型斷言表達(dá)式或者類型斷言+switch語(yǔ)句進(jìn)行判斷
- 對(duì)于已有相應(yīng)變量且類型相同的一系列錯(cuò)誤值, 一般直接使用判等操作 + switch語(yǔ)句
- 沒(méi)有相應(yīng)變量且類型未知的一系列錯(cuò)誤值, 只能使用其錯(cuò)誤信息的字符串表示形式來(lái)判斷
下面我們分別來(lái)看上面的內(nèi)容: 首先是第一點(diǎn), 已知錯(cuò)誤值的范圍比如: {os.PathError|os.LinkError|os.SyscallError|exec.Error}, 是它們中的一個(gè), 我們可以直接使用類型斷言+switch, 然后返回潛在錯(cuò)誤類型
func underlyingError(err error) error {
switch err := err.(type) {
case *os.PathError:
return err.Err
case *os.LinkError:
return err.Err
case *os.SyscallError:
return err.Err
case *exec.Error:
return err.Err
}
return err
}當(dāng)我已經(jīng)知道某個(gè)錯(cuò)誤是哪一個(gè), 我們直接使用判等操作+switch,
printError := func(i int, err error) {
if err == nil {
fmt.println("nil error")
return
}
err = underlyingError(err)
switch err {
case os.ErrClosed:
fmt.Printf("error(closed)[%d]: %s\n", i, err)
case os.ErrInvalid:
fmt.Printf("error(invalid)[%d]: %s\n", i, err)
case os.ErrPermission:
fmt.Printf("error(permission)[%d]: %s\n", i, err)
}
}通過(guò)上面這種直接判等操作, 我們就可以鎖定具體的錯(cuò)誤值了
對(duì)于上面兩種情況, 我們都會(huì)有比較明確的方法去解決, 但是我們對(duì)一個(gè)錯(cuò)誤值可能代表的含義知道的很少, 那么就只能通過(guò)錯(cuò)誤信息去判斷了
到此這篇關(guān)于Go語(yǔ)言中的錯(cuò)誤處理最佳實(shí)踐詳解的文章就介紹到這了,更多相關(guān)Go錯(cuò)誤處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解golang函數(shù)多返回值錯(cuò)誤處理與error類型
- 重學(xué)Go語(yǔ)言之錯(cuò)誤處理與異常機(jī)制詳解
- Go語(yǔ)言中錯(cuò)誤處理的方式總結(jié)
- Go語(yǔ)言中實(shí)現(xiàn)完美錯(cuò)誤處理實(shí)踐分享
- Golang錯(cuò)誤處理方式異常與error
- Golang中的錯(cuò)誤處理深入分析
- Golang中的錯(cuò)誤處理的示例詳解
- Golang中的錯(cuò)誤處理的示例詳解
- Go 代碼規(guī)范錯(cuò)誤處理示例經(jīng)驗(yàn)總結(jié)
- Go?錯(cuò)誤處理實(shí)踐總結(jié)示例
- Go錯(cuò)誤處理的幾種方式
相關(guān)文章
Go語(yǔ)言學(xué)習(xí)筆記之文件讀寫操作詳解
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言對(duì)文件進(jìn)行讀寫操作的方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下2022-05-05
一文詳解Golang協(xié)程調(diào)度器scheduler
這篇文章主要介紹了一文詳解Golang協(xié)程調(diào)度器scheduler,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07
golang中l(wèi)og包自定義輸出日志格式與寫入到文件
這篇文章主要給大家介紹了關(guān)于golang中l(wèi)og包自定義輸出日志格式與寫入到文件的相關(guān)資料,日志輸出在任何項(xiàng)目中都極其重要,是有助于后續(xù)我們排查解決程序BUG,需要的朋友可以參考下2023-06-06
goland配置自動(dòng)注釋的實(shí)現(xiàn)
本文主要介紹了goland配置自動(dòng)注釋的實(shí)現(xiàn),文中通過(guò)圖文示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08
使用Golong實(shí)現(xiàn)JWT身份驗(yàn)證的詳細(xì)過(guò)程
JWT提供了一種強(qiáng)大而靈活的方法來(lái)處理Web應(yīng)用程序中的身份驗(yàn)證和授權(quán),本教程將引導(dǎo)您逐步實(shí)現(xiàn)Go應(yīng)用程序中的JWT身份驗(yàn)證過(guò)程,感興趣的朋友跟隨小編一起看看吧2024-03-03
golang如何用http.NewRequest創(chuàng)建get和post請(qǐng)求
這篇文章主要介紹了golang如何用http.NewRequest創(chuàng)建get和post請(qǐng)求問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
模塊一 GO語(yǔ)言基礎(chǔ)知識(shí)-庫(kù)源碼文件
這篇文章主要介紹了模塊一 GO語(yǔ)言基礎(chǔ)知識(shí)-庫(kù)源碼文件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01

