【发布时间】:2014-10-01 11:52:11
【问题描述】:
require 和 assert 都用于在运行时执行某些检查以验证某些条件。
那么它们之间的基本区别是什么?
我看到的唯一一个是 require throws IllegalArgumentException 和 assert throws AssertionError。
如何选择使用哪一个?
【问题讨论】:
标签: scala
require 和 assert 都用于在运行时执行某些检查以验证某些条件。
那么它们之间的基本区别是什么?
我看到的唯一一个是 require throws IllegalArgumentException 和 assert throws AssertionError。
如何选择使用哪一个?
【问题讨论】:
标签: scala
正如Kigyo 提到的,存在语义差异
还有一个主要的技术区别:
assert 被注释为@elidable(ASSERTION)
这意味着您可以使用-Xelide-below ASSERTION 或-Xdisable-assertions 编译您的程序,并且编译器不会为断言生成字节码。如果您有大量断言,这可以显着减少字节码大小并提高性能。
知道了这一点,您可以使用assert 来验证程序中的所有不变量everywhere(每个方法/函数调用的所有前置条件/后置条件)并且不为生产付出代价。
您通常会在启用所有断言的情况下构建“test”,它会更慢,因为它会始终验证所有断言,然后您可以拥有“production " 没有断言的产品构建,您将消除通过断言完成的所有内部状态检查
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 会保留。
【讨论】:
您可以查看here 了解有关 Scala 语言的详细讨论。
我可以补充一点,区分require和assert的关键是理解这两个。这两者都是软件质量的工具,但来自不同范例的不同工具箱。总而言之,assert 是一种软件测试工具,它采用纠正方法,而require 是一种合同设计工具,采用预防方法。
require 和assert 都是控制状态有效性的方法。从历史上看,处理无效状态有两种不同的范式。第一个是主流统称为软件测试学科方法和工具。另一种称为按合同设计。这是两个没有可比性的范式。
软件测试确保代码具有足够的通用性,能够执行容易出错的操作,并且不会被滥用。 按合同设计控制代码不具有这种能力。换句话说,软件测试是纠正性的,合同设计是预防性的。
assert 用于编写单元测试,即如果一个方法通过了由 assert 表达式编写的所有测试,则代码被认定为无错误。所以assert除了操作代码之外,是一个独立的机构。require 嵌入在代码中,其中一部分是为了确保不会发生任何有害的事情。【讨论】:
用非常简单的语言:
Require 用于对函数的调用者或某个类的对象的创建者强制执行前提条件。而assert 用于检查函数本身的代码。
因此,如果先决条件失败,那么您会得到一个illegal argument exception。然而,如果一个断言失败并且这不是调用者的错,那么你会得到一个assertion error。
【讨论】:
要求、确保和不变性是合同设计 (CBD) 开发过程中的概念。
require 检查调用者在使用例程时应满足的先决条件。
确保检查返回值的正确性(同时验证只发生了所需的更改,仅此而已)
在所有关键时刻对类的有效性进行不变性检查。
CBD 是一种用于构建正确/强大软件的开发方法。有关 CBD Google 的更多详细信息,您应该点击 Eiffel Software 的链接。希望这会有所帮助。
【讨论】:
Scaladocs/javadocs 也不错:
Tests an expression, throwing an AssertionError if false. Calls to this method will not be generated if -Xelide-below is greater than ASSERTION.
Tests an expression, throwing an IllegalArgumentException if false. This method is similar to assert, but blames the caller of the method for violating the condition.
【讨论】: