2011-10-31 41 views
10

在使用F#option類型一段時間後,我意識到它可以用於處理異常情況。我可以在以下實施例中使用兩種或optionException選項vs異常處理異常

  1. find功能從列表/陣列/ SEQ模塊在罕見的情況下提高KeyNotFoundException,而對應tryFind同行在這些情況下返回None
  2. 當我回溯(在解決N皇后,數獨等),只要分支無解,我可以拋出一個異常,後來將其接住或返回無以匹配值原路返回。這些情況經常發生,直到我們找到解決方案。

我的印象是option是一種更爲實用的方法,而Exception更常用於.NET平臺。

optionException在異常處理方面的可用性,性能等方面有什麼區別?在哪些情況下使用一種技術比使用另一種更好?

回答

15

的CLR使得拋出和捕獲異常極其昂貴的操作。僅僅因爲這個原因,你應該更喜歡Option這樣的結構來報告預期的失敗。如果失敗確實是例外並且幾乎無法恢復,請繼續並引發異常。但正如你所看到的那樣,在搜索過程中回溯等事情是無所作爲的,而且如果你用例外來實現它們,你會發現你的性能會受到很大的影響。

因爲這是CLR的一個屬性,它並沒有真正不管你是在F#與否。我的理解是ML類語言的其他運行時間,例如ocaml,沒有這個特性,所以可能更多地使用異常來控制流量。

+0

事實上,我曾測量過這一點,發現C++異常比OCaml慢6倍,而.NET的速度比OCaml慢600倍! –

5

從理論上來看。 option是你應該在那些純粹從FP角度來看的函數中使用的東西(你可以在谷歌中瞭解什麼是純函數)。例外情況更多的是關於不純的世界(像哈斯克爾的IO世界)。

現在從實際的角度來看,我建議使用option作爲返回類型,當你的應用程序的邏輯表示該值可以在那裏,或者它不能存在的值是一個有效的應用程序規則。當應用程序邏輯中發生錯誤的邏輯執行或者某些不正確的應用程序狀態(應用程序規則不符合預期)時,應該引發異常。

從性能POV拋出的例外是更昂貴的(因爲棧展開 - 尋找適當的異常處理 - 等)相比,恢復選項類型爲。

+0

我不同意關於表演的評論。選項類型比Exception類型更輕量級(請參閱@Sebastian Good的答案)。 – pad

+0

我的文字說'異常會壞'..這意味着異常在性能上不好 – Ankur

+0

對不起,我的錯誤是不仔細閱讀:) – pad

4

就可用性而言,我更喜歡F#中的選項。

  • 選項封裝了異常狀態以及預期狀態。這允許您在處理異常狀態之前處理異常狀態,直到您需要預期狀態爲止。
  • 選項也有一個helper functions的數字,你必須自己寫例外。
  • Partial Active Patterns允許您使用選項非常乾淨地處理多個特殊情況。在F#中的
  • Optional Paramaters使用Options實現。我上面提到的這種延遲性質可以讓您不在意是什麼產生了特例,只要消費者具有默認值即可。

選項是一個從根本上不同的思維方式的特殊情況下,我相信有助於使F#特殊。

+0

對於一個非常深思熟慮的答案+1。這就是我想知道的有關在異常處理中使用選項的信息。 – pad

8

我的問題是什麼是異常處理的可用性,性能方面的選項和異常之間的區別...?

option類型提供了比異常更強的靜態檢查,增加了編譯器捕獲程序員錯誤的機會。無異常返回可能比返回Some結果快,但返回異常比返回None慢數百倍。

在哪些情況下使用技術比另一種更好?

每當我編寫需要繼續運行的服務器和守護進程等代碼時,我會捕獲儘可能多的異常,並用option等聯合類型的值替換它們。然後,靜態類型系統迫使我在幾乎所有情況下處理例外和非例外返回,這使得編寫不會因異常意外傳播的異常而死的代碼變得更容易。