Difference between "precondition" and "assert" in swift?

What's the difference between precondition(condition: Bool, message: String) and assert(condition: Bool, message: String) in Swift?

Both of them look same to me. In which context should we use one over the other?

28885 次浏览

precondition在发布模式下处于活动状态,所以当您发布应用程序时,如果前提条件失败,应用程序将终止。 Assert默认只在调试模式下工作。

I found this great explanation when to use it on NSHipster:

断言是从经典逻辑学中借鉴而来的概念, assertions are statements about propositions within a proof. In 断言表示程序员已经做出的假设 在申报地点填写有关申请的资料。

当以前置条件和后置条件的容量使用时, 在开始时描述对代码状态的期望,并且 方法或函数的执行结束时,断言形成契约。 断言还可用于在运行时强制执行条件 当某些前提条件失败时,阻止执行。

先决条件

func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

检查取得进展的必要条件。

  1. 使用此函数检测必须阻止程序的条件 甚至在运输代码中也不能进行。
  2. 在游乐场和 -Onone 构建(Xcode 的 Debug 的默认设置 Configuration) : 如果条件计算结果为 false,则停止程序 在打印消息后以可调试状态执行。
  3. In-O 构建(Xcode 的发布配置的默认值) : if 条件的计算结果为 false,停止程序执行。
  4. In-Ouncheck 生成中,不计算条件,但计算优化器 可以假设它会被评估为真 假设在-未检查的构建是一个严重的编程错误。

断言

func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

带有可选消息的传统 C 样式断言。

  1. 使用此函数进行内部健全性检查,这些检查在 测试,但不影响运送代码的性能 在发布版本中使用无效; 请参阅前置条件

  2. 在游乐场和 -Onone 构建(Xcode 的 Debug 的默认设置 Configuration) : 如果条件计算结果为 false,则停止程序 在打印消息后以可调试状态执行

  3. In -O builds (the default for Xcode's Release configuration), 条件不进行评估,并且没有影响
  4. In-Ouncheck 生成中,不计算条件,但计算优化器 可以假设它会被评估为真 未检查的构建是一个严重的编程错误

assert is for sanity checks during testing, whereas precondition is for guarding against things that, if they happen, would mean your program just could not reasonably proceed.

So for example, you might put an assert on some calculation having sensible results (within some bounds, say), to quickly find if you have a bug. But you wouldn’t want to ship with that, since the out-of-bound result 也许吧 be valid, and not critical so shouldn’t crash your app (suppose you were just using it to display progress in a progress bar).

另一方面,当提取元素时,检查数组上的下标是否有效是 precondition。当数组对象被要求使用无效下标时,没有合理的下一步操作,因为它 必须的返回一个非可选的值。

来自文档的全文(尝试选项-单击 Xcode 中的 assertprecondition) :

前提条件

检查取得进展的必要条件。

使用此函数检测必须防止 program from proceeding even in shipping code.

  • In playgrounds and -Onone builds (the default for Xcode's Debug 配置) : 如果 condition计算结果为 false,则停止程序 在打印 message后以可调试状态执行。

  • In-O 构建(Xcode 的发布配置的默认值) : 如果 condition的计算结果为 false,则停止程序执行

  • 未检查生成时,不计算 condition,但计算 optimizer may assume that it evaluate to true. Failure 为了满足这个假设-Ouncheck 构建是一个严重的 编程错误

坚持

带有可选消息的传统 C 样式断言。

使用此函数进行活动的内部健全性检查 但不会影响传送代码的性能。 To check for invalid usage in Release builds; see precondition.

  • 在游乐场和 -Onone 构建(Xcode 的 Debug 的默认设置 配置) : 如果 condition计算结果为 false,则停止程序 execution in a debuggable state after printing message.

  • In-O 构建(Xcode 的发布配置的默认值) , 没有评估 condition,也没有效果

  • 未检查生成时,不计算 condition,但计算 优化器可能假设它的 would计算为 true to satisfy that assumption in -Ounchecked builds is a serious 编程错误

我发现 斯威夫特断言——缺失的手册很有用

                        debug   release   release
function                -Onone  -O       -Ounchecked
assert()                YES     NO        NO
assertionFailure()      YES     NO        NO**
precondition()          YES     YES       NO
preconditionFailure()   YES     YES       YES**
fatalError()*           YES     YES       YES

还有 关于迅速进化的有趣讨论

– assert: checking your own code for internal errors

- 前提条件: 检查你的客户是否给了你有效的论据。

另外,您需要注意使用什么,请参阅 失败和优化级别

我只是想多说两句。您可以在代码中添加任意多的断言。您可以使用这些断言发送代码。Swift 不会为生产应用程序评估这些代码块。这些只在调试模式下进行计算。

添加文档链接

同时附上来自 Swift. org 的图片

enter image description here

Also note, this is not the case with preconditions. 如果前置条件没有被评估为真,那么带有前置条件的代码将崩溃,应用程序将终止。

因此,简而言之,断言是用于调试的,但可以在不影响生产的情况下发布。断言将在调试模式下计算,但不会在生产环境中计算。

还有

前置条件是为了确保在生产环境中不会发生意想不到的事情。这些条件将被评估,并将终止您的应用程序,以防它们被评估为错误