require
和assert
都用於在運行時期間執行某些檢查以驗證某些條件。在scala中require和assert之間做什麼選擇
那麼他們之間的基本區別是什麼?
我看到的唯一一個是require
拋出IllegalArgumentException
和assert
拋出AssertionError
。
如何選擇使用哪一個?
require
和assert
都用於在運行時期間執行某些檢查以驗證某些條件。在scala中require和assert之間做什麼選擇
那麼他們之間的基本區別是什麼?
我看到的唯一一個是require
拋出IllegalArgumentException
和assert
拋出AssertionError
。
如何選擇使用哪一個?
由於Kigyo提到的是有語義差別
還有一個主要的技術區別:
assert
標註有@elidable(ASSERTION)
這意味着你可以用-Xelide-below ASSERTION
或-Xdisable-assertions
編譯程序和編譯器不會生成斷言字節碼。如果您有大量斷言,這可以顯着減少字節碼大小並提高性能。
知道了這一點,你可以用一個assert
驗證所有不變量到處在你的程序(每個單獨的方法/函數調用的所有前提條件/後置),並沒有付出代價的生產。
你會通常有「測試」建立並啓用,這將是更慢,因爲這將驗證在任何時候都斷言的所有斷言,那麼你可以有「生產」你的產品的構建沒有斷言,你會消除通過斷言完成的所有內部狀態檢查
require
不是可以消除的,它更適合用於庫(包括內部庫)來通知調用者調用給定方法的前提條件/功能。
這只是我的主觀觀點。當我想要參數約束時,我使用require
。
作爲一個例子,我們可以採用自然數的階乘。由於我們不想處理負數,我們想要投出IllegalArgumentException
。
我會使用assert
,只要你想確保一些條件(如不變式)在執行過程中總是爲真。我把它看作是一種測試方式。
這裏是一示例實現階乘與require
和assert
def fac(i: Int) = {
require(i >= 0, "i must be non negative") //this is for correct input
@tailrec def loop(k: Int, result: Long = 1): Long = {
assert(result == 1 || result >= k) //this is only for verification
if(k > 0) loop(k - 1, result * k) else result
}
loop(i)
}
result > 1
時爲真,則該循環被執行至少一次。所以結果必須大於或等於k
。這將是一個循環不變。
如果您確定自己的代碼是正確的,則可以刪除assert
,但require
可以保留。
所以基本上它只是爲了理解目的,沒有其他區別 – Roshan 2014-10-01 12:38:04
當給定的條件不滿足時,它們都拋出異常。這只是例外情況,是的。 – Kigyo 2014-10-01 12:40:57