我大多數時間使用Either
,沒有例外。我通常會使用異常,就像你已經做過的或者類似的方式一樣,當控制流程必須走回頭路,回到某個遙遠的點時,否則就沒有什麼明智的做法。然而,當異常還算可以在本地處理,我會代替
def myMethod(...): Either[String,ValidatedInputForm] = {
...
if (!someHelper(...)) Left("Agree button not checked")
else Right(whateverForm)
}
,然後當我把這種方法,我可以
myMethod(blah).fold({ err =>
doSomething(err)
saneReturnValue
}, { form =>
foo(form)
form.usefulField
})
上
Left(err)
或比賽VS Right(form)
,或各種其他的東西。
如果我不想處理錯誤在那裏,而是要處理的返回值,我
myMethod(blah).right.map{ form =>
foo(form)
bar(form)
}
,我會得到一個Either
與錯誤信息不變爲Left
,如果是錯誤消息,或者{ foo(form); bar(form) }
的結果爲Right
(如果沒有問題)。您還可以使用flatMap
鏈接錯誤處理,例如如果你想執行就這麼遠,正確的價值觀額外的檢查,並拒絕其中的一些,你可以
myMethod(blah).right.flatMap{ form =>
if (!checkSomething(form)) Left("Something didn't check out.")
else Right(form)
}
它的這種處理,這使得使用Either
更方便(通常是更好的表現,如果異常是常見的)比例外,這就是我使用它們的原因。
(事實上,在很多情況下,我不關心爲什麼出事了,只是出了問題,在這種情況下,我只使用一個Option
)
咦?例外是準確的這種情況!以便與用戶通信的應用程序部分可與系統的其他部分分離。如果'someHelper'是用於轉換源自用戶的數據的本地有用函數,那麼肯定不應該知道如何與用戶通信以顯示錯誤消息。爲了驗證它,通信模塊可能不應該知道對'someHelper'數據的要求。 – Ben 2011-12-22 04:02:45
被警告。創建異常會填充堆棧跟蹤,這可能是一項昂貴的操作。如果你走這條路線,按名稱傳遞異常,所以它只在你使用它時創建:'def someMethod(e:=> Exception)'。 – leedm777 2011-12-22 04:34:58
@Ben我的意思是,這些異常不是用來保存應用程序的狀態信息,而是通過異常實例傳遞(而不是拋出)並用邏輯圍繞它們看起來非常像這樣 – 2011-12-22 05:49:58