我有一個Scala幫助器方法,它目前試圖獲取一個URL並返回一個Option [String]與該網頁的HTML。更好地返回無或提取URL時引發異常?
如果有任何異常(格式不正確,讀取超時等),或者如果有任何問題,則返回無。問題是,拋出異常以便調用代碼能夠記錄異常,還是最好在這種情況下返回None?更好嗎?
我有一個Scala幫助器方法,它目前試圖獲取一個URL並返回一個Option [String]與該網頁的HTML。更好地返回無或提取URL時引發異常?
如果有任何異常(格式不正確,讀取超時等),或者如果有任何問題,則返回無。問題是,拋出異常以便調用代碼能夠記錄異常,還是最好在這種情況下返回None?更好嗎?
創建異常很昂貴,因爲必須填寫堆棧跟蹤。投擲和捕捉異常也比正常回報更昂貴。考慮到這一點,你可能會問自己以下問題:
你想調用者強制錯誤的處理?如果是這樣,不要拋出異常,因爲Scala沒有檢查異常機制,強制調用者捕獲它們。
如果發生錯誤,是否要包含有關失敗原因的詳細信息?如果不是,您可以返回Option[A]
,其中A
是您的返回類型,然後您將有Some(validContent)
或None
,沒有其他解釋。如果是的話,你可以返回像Either[E, A]
或斯卡拉茲Validation[E, A]
。所有這些選項強制調用者以某種方式解開結果,同時按照自己的意願自由處理錯誤E
。那麼E
應該是什麼?
您是否想在出現故障時提供堆棧跟蹤?如果是這樣,你可以可以返回Either[Exception, A]
或Validation[Exception, A]
。如果你真的去除了例外,你會想要使用Try[A]
,其中兩種可能的情況是Failure(exc: Throwable)
和Success(value: A)
。請注意,您當然會產生創建throwable的成本。如果不是,你可能只需要返回Either[String, A]
(並且要特別小心,以記住Right
是否意味着成功或失敗 - Left
通常用於錯誤,而Right
用於「正確」值 - Validation
也許更清楚)。如果你想可選返回堆棧跟蹤,你可以使用電梯的Box[A]
,這可能是Full(validContents)
,Empty
沒有額外的解釋(非常類似於Option[A]
了這裏),或表示Failure
它可以存儲一個錯誤字符串和/或一個可拋(更多)。
你也許想提供多種說明,說明它爲什麼失敗?然後返回Either[Seq[String], A]
。如果你經常這樣做,你可能會想用Scalaz和Validation[NonEmptyList[String], A]
來代替,它提供了一些其他的好東西。看看它的更多信息或退房these usage examples。
偉大的總結!就個人而言,我大部分時間都使用[String,...],但斯卡拉茲的驗證似乎更清晰。 –
我認爲,在這種情況下,如果重要的是要記錄異常,然後通過各種手段拋出的異常(也可能只是返回字符串而不是選項)。否則,你可能只是返回無。一個警告 - 可能會出現其他原因的例外情況,您無法預見,在這種情況下,編寫一段代碼可能會很危險。
你可以做的一件事就像Lift的Box
系統。一個盒子本質上是一個選項,但添加了幾個功能:A Full
就像一個Some
,Empty
就像一個None
,但電梯更進一步,有一個Failure
,這就像一個Empty
,但有一個原因/信息。
一般的經驗法則是「如果你能處理異常,處理它」。所以沒有足夠的上下文來猜測。您可以使用tryFetchUrl/fetchUrl對方法。
如果是輔助方法,我認爲它是私人的。如果它是私人的,那麼你是來電者。如果你是來電者,那麼你就是擁有關於應該發生什麼的所有信息的人,所以做任何你想要的。否則,請看Jean的答案。 – agilesteel