2 回答

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超13個贊
一些歷史:
在 Go 的早期(1.0 版之前),沒有recover()
. 調(diào)用panic()
將終止應(yīng)用程序而沒有任何方法可以阻止它。
我找到了導(dǎo)致添加的原始討論recover()
,您可以在 golang-nuts 討論論壇上閱讀它:
類似異常機(jī)制的提議
請注意:討論可以追溯到 2010 年 3 月 25 日,而且相當(dāng)冗長(150 個帖子,共 6 頁)。
最終它是在2010-03-30添加的:
此版本包含三個語言更改:
用于報(bào)告和從故障中恢復(fù)的函數(shù)
panic
andrecover
已添加到規(guī)范中:
http : //golang.org/doc/go_spec.html#Handling_panics
在相關(guān)更改中,panicln
已消失,panic
現(xiàn)在是單參數(shù)函數(shù). gc 編譯器可以識別恐慌和恢復(fù),但新行為尚未實(shí)現(xiàn)。
多返回值和約定提供了一種更清晰的方式來處理 Go 中的錯誤。
然而,這并不意味著在某些(罕見的)情況下,恐慌恢復(fù)沒有用。
引用官方FAQ:為什么Go沒有異常?
Go 還具有一些內(nèi)置函數(shù),用于發(fā)出信號并從真正的異常情況中恢復(fù)?;謴?fù)機(jī)制僅在發(fā)生錯誤后被拆除的函數(shù)狀態(tài)的一部分執(zhí)行,這足以處理災(zāi)難,但不需要額外的控制結(jié)構(gòu),如果使用得當(dāng),可以產(chǎn)生干凈的錯誤處理代碼。
這是一個關(guān)于何時/如何有用的“現(xiàn)實(shí)生活”示例:引自博客文章Defer, Panic and Recover:
有關(guān)panic和recovery的真實(shí)示例,請參閱Go 標(biāo)準(zhǔn)庫中的json 包。它使用一組遞歸函數(shù)解碼 JSON 編碼的數(shù)據(jù)。當(dāng)遇到異常JSON,解析器呼叫恐慌展開棧到頂層的函數(shù)調(diào)用,從恐慌并返回一個適當(dāng)?shù)腻e誤值中恢復(fù)(見“錯誤”,并在decodeState類型的“解組”方法的解碼.去)。
另一個例子是當(dāng)您編寫調(diào)用用戶提供的函數(shù)的代碼(例如包)時。您不能相信所提供的功能不會恐慌。一種方法是不處理它(讓恐慌結(jié)束),或者您可以選擇通過從這些恐慌中恢復(fù)來“保護(hù)”您的代碼。一個很好的例子是標(biāo)準(zhǔn)庫中提供的http 服務(wù)器:您提供服務(wù)器將調(diào)用的函數(shù)(處理程序或處理程序函數(shù)),如果您的處理程序發(fā)生恐慌,服務(wù)器將從這些恐慌中恢復(fù)并且不會讓您的完整應(yīng)用程序模具。
你應(yīng)該如何使用它們:
Go 庫中的約定是,即使包在內(nèi)部使用 panic,其外部 API 仍會顯示明確的錯誤返回值。

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個贊
我認(rèn)為您的問題是您維護(hù)的一種心理模型的結(jié)果,該模型是由流行的主流語言(例如 Java、C++、C#、PHP 和無數(shù)其他語言)灌輸?shù)?,這些語言只是錯誤地出現(xiàn)了異常。
問題是,異常本身并不是一個錯誤的概念,而是濫用它們來處理實(shí)際上并非異常的情況。我個人最討厭的是 Java 的文件系統(tǒng)處理 API(和 .NET,它幾乎逐字復(fù)制了 Java 的 API):如果該文件不存在,為什么無法打開文件會導(dǎo)致異常?文件系統(tǒng)是一種固有的 racy 媒體,并被指定為 racy,因此在打開文件進(jìn)行讀取之前確保文件存在的唯一正確方法是打開它然后檢查“文件不存在”錯誤:不存在的文件一點(diǎn)也不例外。
因此,Go 清楚地將異常情況與普通的正常錯誤區(qū)分開來。Go 處理錯誤的立場的座右銘是“錯誤就是值”,因此正常的預(yù)期錯誤作為值處理,并panic()
用于處理異常情況。一個很好的簡單例子:
嘗試取消引用
nil
指針會導(dǎo)致panic
.基本原理:您的代碼繼續(xù)并嘗試取消引用不指向任何值的指針。緊隨其后的代碼明確期望該值可用——作為解引用操作的結(jié)果。因此,控制流顯然不能以任何合理的方式正常進(jìn)行,這就是為什么這是一種例外情況:在正確的程序中,
nil
指針的解引用不會發(fā)生。TCP 流的遠(yuǎn)程端突然關(guān)閉了其一側(cè)的流,下一次嘗試讀取它導(dǎo)致錯誤。
這是很正常的情況:人們不能理智地期望 TCP 會話是堅(jiān)如磐石的:網(wǎng)絡(luò)中斷、數(shù)據(jù)包丟失、意外斷電確實(shí)會發(fā)生,我們必須為遠(yuǎn)程對等方意外關(guān)閉流做好準(zhǔn)備。
一個小小的轉(zhuǎn)折panic()
是 Go 不會強(qiáng)迫你盲目地遵循某些教條,并且你可以在嚴(yán)格控制的特定情況下自由地“濫用”恐慌/恢復(fù),例如panic
國王用錯誤值從深度嵌套的處理循環(huán)中跳出已知并在現(xiàn)場檢查的特定類型recover
。
- 2 回答
- 0 關(guān)注
- 161 瀏覽
添加回答
舉報(bào)