二者require并assert用于在运行时期间执行某些检查,以验证某些条件.
那么它们之间的基本区别是什么?
我看到的唯一一个是require投掷IllegalArgumentException和assert投掷AssertionError.
如何选择使用哪一个?
Jea*_*ean 72
正如Kigyo所说,存在语义差异
还有一个主要的技术差异:
assert注释的@elidable(ASSERTION)
意思是您可以使用-Xelide-below ASSERTION或编译程序, -Xdisable-assertions编译器不会生成断言的字节码.如果您有大量断言,这可以显着减少字节码大小并提高性能.
知道了这一点,你可以使用assert来验证一切的不变量无处不在您的程序(每个单独的方法/函数调用的所有前提条件/后置),并没有付出代价的生产.
你通常会在启用所有断言的情况下进行" 测试 "构建,因为它会在任何时候验证所有断言都会变慢,然后你可以在没有断言的情况下进行产品的" 生产 "构建,这样你就可以消除通过断言完成所有内部状态检查
require 如果不是elidable,在库(包括内部库)中使用更有意义来通知调用者调用给定方法/函数的前提条件.
Kig*_*gyo 21
这只是我的主观观点.
require每当我想要参数约束时我都会使用.
作为一个例子,我们可以采用自然数的阶乘.由于我们不想解决负数,我们想要抛出一个IllegalArgumentException.
我会使用assert,只要你想确保某些条件(如不变量)在执行期间始终为真.我认为这是一种测试方式.
以下是使用require和的factorial的示例实现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)
}
Run Code Online (Sandbox Code Playgroud)
如果result > 1为true,则循环至少执行一次.所以结果必须大于或等于k.这将是一个循环不变量.
当你确定你的代码是正确的,你可以删除assert,但require会留下.
您可以在此处查看Scala 语言的详细讨论。
我可以补充一点,区分require和的关键assert是理解这两者。这两个都是软件质量工具,但来自不同范式的不同工具箱。总之assert,软件测试工具采用纠正方法,而require合同设计工具采用预防方法。
和require都是assert控制状态有效性的手段。历史上有两种不同的范式来处理无效状态。第一个是主流,统称为软件测试学科方法和工具。另一种称为合同设计。这是两个没有可比性的范式。
软件测试确保代码具有足够的通用性,能够执行容易出错的操作,并且不会被滥用。通过契约设计控制代码不具备这种能力。换句话说,软件测试是纠正性的,而契约设计是预防性的。
assert用于编写单元测试,即如果一个方法通过了表达式编写的所有测试assert,则该代码被认为是无错误的。所以assert席位除了运营代码之外,而且是一个独立的机构。require嵌入到代码及其一部分中,以确保不会发生任何有害的情况。