Go語言error的設(shè)計理念及背景演化詳解
背景
作為一門相對新興的語言,Go 可以說是站在巨人的肩膀上。從 Go 語法上,我們可以看出設(shè)計者對其有許多嚴肅的思考。其中 Error 的處理就是極具標志性的一項。
值得注意的是,Go 中的 Error 一直是一個有爭議的內(nèi)容。很多議案不斷的提出又推翻,即便是官方的 error 庫也在多個版本中不斷迭代。本文內(nèi)容基于 1.19.3 版本的 Go 編寫。
各語言中 Error 的演化
想要了解 Error 在 Go 中占據(jù)話題的原因,我們需要先了解 Error 在編程語言中的演化。
C語言
C語言中開發(fā)者需要根據(jù)函數(shù)的返回值作錯誤判斷。每個函數(shù)是單返回值,一般通過傳遞指針作為入?yún)ⅰ7祷刂禐?int 類型,表示成功或失敗。
顯然在這個階段,語言設(shè)計者只單純地把錯誤考慮為“異常”情況,由開發(fā)者判斷函數(shù)的執(zhí)行結(jié)果。這種情況下,錯誤中并沒有太多信息。這會加重開發(fā)者對錯誤的處理工作。
C++
進入C++時代以后,語言帶來了 exception 。錯誤會作為一個程序正常執(zhí)行以外的一個特殊情況被拋出。而開發(fā)者可以通過 try....catch.... 對異常作特殊處理。
這種設(shè)計模式的影響很廣,包括 Javascript 在內(nèi)很多語言都延續(xù)了這種設(shè)計。其特點為,開發(fā)者可以知道錯誤在哪里拋出,但不能具體知道調(diào)用方會拋出什么異常。
Go 中 Error 的理念
在 Go 的 Error 中,我們可以看到兩個 ERROR 的特點。
1. 區(qū)分 Error 和 Exception
第一點是,Go 中真正從語言設(shè)計上區(qū)分開了 Error 和 Exception。Go 的處理異常邏輯不引入 exception ,支持多參數(shù)返回,所以開發(fā)者可以很容易在函數(shù)簽名中帶上實現(xiàn)了 error interface 的對象,交由調(diào)用者處理。
通常如果一個函數(shù)返回了 value 和 error , 開發(fā)者需要先判定 error,再利用處理 value 處理下一步邏輯。常見代碼如下:
value, err := getSomething() if err != nil{ // 處理錯誤 return } // 邏輯處理
另外,Go 中引入了 panic 機制,它與其他語言的 exception 不完全一樣。在其他語言中,當程序拋出異常時,相當于把 exception 拋給開發(fā)者處理。而 Go 中的 panic 是專門,針對真正意外,不可恢復(fù)的情況,如索引越界、不可恢復(fù)的環(huán)境問題、棧溢出。
同時,GO 也提供了從 panic 中恢復(fù)的接口—— recover 。但這不意味著開發(fā)者應(yīng)該把其當作 try... catch... 使用。而是應(yīng)該當作是程序崩潰后的特殊處理的最后機會。在 Go 的設(shè)計中,panic 一旦觸發(fā),說明程序應(yīng)該要退出了。但在某些業(yè)務(wù)場景下,我們可能還會有日志上報,日志打印,信息通知等操作。此時,就應(yīng)該考慮使用 recover。
2.Error是一個接口
第二點是,Error 在 Go 中其實是一個普通的接口。它不僅保存著錯誤的信息,還提供了一系列的方式供開發(fā)者使用。因此開發(fā)者可以自行拓展,嵌套,封裝新的 error ,為項目提供自定義錯誤模塊。
由此看來,Error 在 Go 中并不像其他語言一樣,是一個特殊的類型。它只是一個普通的值,開發(fā)者完全可以自己實現(xiàn)一套新的 Error 接口。但更多時候,官方的 errors 庫已經(jīng)可以覆蓋絕大多數(shù)場景了。
因此, Go 的設(shè)計并不是在定義一套新的 Error 機制。而是在制定一套 Error 在代碼邏輯中處理的規(guī)范。你不必完全遵守這套規(guī)范,但在各種實際開發(fā)經(jīng)驗總結(jié)來看,Go 的這種設(shè)計模式確實贏得了很多開發(fā)者的青睞。
示例代碼:
// 創(chuàng)建一個error newErr := errors.New("一個錯誤") // 判斷error類型 if errors.Is(newErr, fs.ErrNotExist) { fmt.Println("file does not exist") } else { fmt.Println(err) }
總結(jié)
Go 之所以從誕生至今,吸引了這么多的粉絲。處理語言的機制以外,更多的就是它的設(shè)計理念。而本文講述的 error 就是其中一部分。我們在使用 Go 開發(fā)時,除了按照它推薦的規(guī)范編碼至于,還應(yīng)該關(guān)心、理解它的設(shè)計。只有這樣,才能寫出更優(yōu)秀的作品。
進一步閱讀 官方 errors 庫文檔地址:pkg.go.dev/errors
以上就是Go語言error的設(shè)計理念及背景演化詳解的詳細內(nèi)容,更多關(guān)于Go error設(shè)計理念的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于Go?goroutine實現(xiàn)一個簡單的聊天服務(wù)
對于聊天服務(wù),想必大家都不會陌生,因為在我們的生活中經(jīng)常會用到,本文我們用?Go?并發(fā)來實現(xiàn)一個聊天服務(wù)器,這個程序可以讓一些用戶通過服務(wù)器向其它所有用戶廣播文本消息,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下2023-06-06golang 實現(xiàn)interface{}轉(zhuǎn)其他類型操作
這篇文章主要介紹了golang 實現(xiàn)interface{}轉(zhuǎn)其他類型操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12go內(nèi)存隊列l(wèi)ist VS slice實現(xiàn)方式對比分析
這篇文章主要為大家介紹了go內(nèi)存隊列l(wèi)ist VS slice實現(xiàn)方式對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08