2009-07-21 33 views
5

使用異常處理非錯誤處理案例是否是一種很好的做法?使用異常處理非錯誤目的

就像管理髮生器中的StopIteration情況的JavaScript和Python(yield關鍵字)一樣。

+0

應該是社區wiki。 – SilentGhost 2009-07-21 14:50:31

+0

顯然沒有答案涉及JavaScript和Python使用異常來中斷執行流程。 – 2009-07-21 14:57:24

回答

8

這取決於語言。每種語言都有自己的設計和成語。對於大多數語言來說,例外應該是例外。

在像C++,Java和C#這樣的語言中,使用異常來處理其他事情是非常糟糕的形式。

在Python中,例外被更頻繁地用於像迭代結束之類的事情。還有更多的嘗試去做你想要的東西,並在晚些時候處理例外情況,而不是驗證輸入(「比容許更容易提出寬恕」)。例如,如果你想打開一個文件,你可以用Java檢查它是否存在,然後打開它並檢查你是否有合法的流。在Python中,你可以打開它並使用它。如果失敗,則處理異常。

wikipedia文章:

Python的風格要求使用,只要一個錯誤條件可能會出現異常。在實際使用文件或資源之前,不要測試對文件或資源的訪問權限,而只是繼續前進並嘗試使用它,在訪問被拒絕時捕獲異常。

即使錯誤沒有問題,異常也可以用作非本地控制轉移的更一般的方法。例如,用Python編寫的Mailman郵件列表軟件在決定拒絕一條消息或讓其批准審批時,使用異常跳出深層嵌套的消息處理邏輯。

11

我會說不,自發地。例外情況應該用於特殊的狀態,不適用於正常的程序流程。

+4

有時候,區分例外和常規情況並不那麼容易。 – 2009-07-21 14:52:25

+0

謹慎舉例? – tomfanning 2009-07-21 14:58:21

+0

@Suobok我很難區分何時難以區分。你能舉出一個例子:在正常情況和異常情況之間線條模糊了嗎? – 2009-07-21 15:19:34

10

通常不,不。 ASP.NET將它用於Response.Redirect - 實際中止線程,然後捕獲異常並重置它。這是非常討厭的,但它確實讓你基本上「退出」的請求沒有意識到它需要立即返回的堆棧的每個級別。

儘量避免可能。如果你認爲你絕對有這樣做,請諮詢兩位同事,介紹設計並詢問他們是否可以以更乾淨的方式做到這一點。如果沒有人能想出更好的方法,請用大量文檔來完成。

3

正如名稱所說,異常只能用於例外情況。我不會用它來管理非錯誤情況。

2

編號

例外只應用於特殊情況(如名稱所述)。這意味着:錯誤。

  • 「呃,我找不到這個文件。」 - 異常!
  • 「呃,我不能被0除。」 - 例外!
  • 「呃,我不能沒有記憶。」 - 例外!
  • 「的結果是2.5。」 - 無異常
1

一般系統的目的是使非異常情況下快速,同時接受特殊情況下采取的性能損失。因此一個!很多例外的被拋出/捕獲會比常規結構更慢。

這也使得分析和理解代碼困難,大部分代碼花費大量的時間在維修。

2

這是一個非常q可疑的做法。如果你認爲這是對你的情況最好的事情,不管如何,一定要記錄和註釋它徹底,以保持你的WTF/m關閉。

1

我相信有時候例外情況對於建設DSL s很有用。我知道,這聽起來很奇怪,但由於很多語言沒有Ruby的特性(返回關鍵字是可選的,因爲返回的是最後一次評估表達式的結果),所以我們使用我們所能做到的。

比如,最近我試圖建立一些JavaScript測試框架,我就想辦法爲框架,用戶可以說:的

skip(); 
pending("pending message"); 
fail("failure message"); 

代替:

return skip(); 
return pending("pending message"); 
return fail("failure message"); 

這些函數是庫函數,它會拋出例如SkipTest異常的異常。唯一推薦使用它們的地方是測試方法。這些測試方法總是在try/catch塊中執行,其中處理每種類型的異常,並根據異常情況框架採取適當的步驟。

這是一個例子,我使用Exceptions來控制流程。

這裏有一個小例子:

$.it("should offer means to explicitly mark a spec as failed", function() { 
    $.fail("this spec must fail"); 
}); 
2

在數獨解算我寫的,一個異常的情況下,拋出讓人不解的是解決

主搜索函數是一個私有方法,它通過對其自身進行遞歸調用而下降到搜索樹中。 正常的情況是未能解決這個難題,這隻會導致對調用者的正常返回; 例外案例在解決這個難題方面取得了成功,在這種情況下,我們用公開的方法「拋出(解決方案)」到catch子句。

像這樣的東西是在Scheme中使用call/cc的已知習語。我在我的C++程序中模仿。

我很高興聽到任何人對此方法的贊成或反對意見。