what to choose between require and assert in scala
require和assert都用于在运行时执行某些检查以验证某些条件。
那么它们之间的基本区别是什么?
我唯一看到的是require抛出IllegalArgumentException,而assert抛出AssertionError。
如何选择使用哪一个?
正如Kigyo提到的,在语义上存在差异
-
assert表示您的程序已进入不一致状态,这可能是当前方法/函数存在的问题(我想将其视为HTTP 500 InternalServerError)
-
require意味着该方法的调用者有错误,应该修复它的调用(我喜欢将其视为HTTP 400 BadRequest)
还有一个主要的技术差异:
assert用@elidable(ASSERTION)注释
这意味着您可以使用-Xelide-below ASSERTION或-Xdisable-assertions编译程序,并且编译器将不会为断言生成字节码。如果您有大量的断言,这可以显着减小字节码的大小并提高性能。
知道了这一点,您可以使用assert来验证程序中所有地方的所有不变量(每个方法/函数调用的所有前提条件/后置条件),而无需付出生产上的代价。
通常,您将启用所有断言的"测试"构建,这会变慢,因为它将始终验证所有断言,然后您可以在没有断言的情况下进行产品的"生产"构建,这将消除通过断言完成所有内部状态检查
require是不可省略的,对于在库(包括内部库)中使用来通知调用方调用给定方法/函数的前提条件更有意义。
-
值得注意的是"异常"和"错误"之间的区别(更为严重)。
这只是我的主观观点。
每当我想对参数进行约束时,都使用require。
例如,我们可以将阶乘用于自然数。由于我们不想处理负数,因此我们想抛出IllegalArgumentException。
每当您要确保某些条件(如不变式)在执行期间始终为真时,我将使用assert。我认为这是一种测试方式。
这是使用require和assert的阶乘的示例实现
1 2 3 4 5 6 7 8 9 10 11
| 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为true时,循环至少执行一次。因此,结果必须大于或等于k。那将是一个循环不变式。
当您确定代码正确无误时,可以删除assert,但require会保留。
-
所以基本上它只是出于理解的目的,没有其他区别
-
当不满足给定条件时,它们都将引发异常。 唯一的例外就是不同,是的。
用非常简单的语言:
require用于对某个类的函数的调用者或对象的创建者强制执行先决条件。而assert用于检查函数本身的代码。
因此,如果前提条件失败,那么您将得到一个illegal argument exception。而如果断言失败并且不是调用者的错,那么您将得到一个assertion error。
需求,确保和不变性是按设计合同(CBD)开发过程中的概念。
需要检查调用者使用该例程应满足的前提条件。
确保检查返回值的正确性(并仅验证是否发生了所需的更改,仅此而已)
不变在所有关键时刻检查类的有效性。
CBD是一种构建正确/强大软件的开发方法。有关CBD Google的更多详细信息,您应该点击Eiffel Software的链接。希望这可以帮助。