swift中“前置条件”和“断言”之间的区别?

时间:2015-04-16 11:14:02

标签: swift

Swift中precondition(condition: Bool, message: String)assert(condition: Bool, message: String)之间有什么区别?

他们两个看起来都一样。我们应该在哪种情况下使用另一种?

5 个答案:

答案 0 :(得分:110)

assert用于在测试期间进行健全性检查,而precondition则用于防范事情,如果这些事情发生,则意味着您的计划无法合理地进行。

因此,举例来说,你可能会在某些计算中加上一个assert来获得合理的结果(比如在某些范围内),以便快速找到你是否有错误。但是您不希望随附这些内容,因为超出范围的结果可能有效,并且不重要所以不应该崩溃您的应用程序(假设您只是使用它来显示进度在进度栏中。)

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

文档中的全文(尝试点击Xcode中的assertprecondition选项):

<强>前提条件

  

检查前进的必要条件。

     

使用此功能检测必须阻止的条件   程序甚至在运输代码中进行。

     
      
  • 在playgrounds和-Onone构建中(Xcode的Debug的默认值)   配置):如果condition的计算结果为false,则停止程序   打印message后以可调试状态执行。

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

  •   
  • 在-Ounchecked构建中,condition未被评估,但是   优化器可以假设评估为true。失败   在-Ounchecked构建中满足该假设是一个严重的问题   编程错误。

  •   

<强>断言

  

带有可选消息的传统C风格断言。

     

使用此功能进行活动的内部健全性检查   在测试期间但不影响运输代码的性能。   检查发布版本中的无效用法;见precondition

     
      
  • 在playgrounds和-Onone构建中(Xcode的Debug的默认值)   配置):如果condition的计算结果为false,则停止程序   打印message后以可调试状态执行。

  •   
  • In -O builds(Xcode的Release配置的默认设置),   condition未被评估,并且没有任何影响。

  •   
  • 在-Ounchecked构建中,condition未被评估,但是   优化器可以假设评估为true。失败   在-Ounchecked构建中满足该假设是一个严重的问题   编程错误。

  •   

答案 1 :(得分:72)

我发现Swift asserts - the missing manual有帮助

                        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

来自Interesting discussions on Swift Evolution

  

- 断言:检查自己的代码是否存在内部错误

     

- 前提条件:检查您的客户是否给了您有效的参数。

此外,您需要注意使用的内容,请参阅assertionFailure and Optimization Level

答案 2 :(得分:9)

precondition在发布模式下处于活动状态,因此您在发布应用时前提条件失败,应用将终止。 Assert默认情况下仅在调试模式下工作。

我在NSHipster上使用它时发现了这个很好的解释:

  

断言是从经典逻辑借来的概念。在逻辑上,   断言是关于证明中的命题的陈述。在   编程,断言表示程序员所做的假设   关于申请地点的申请。

     

当用于前提条件和后置条件的能力时,其中   描述对开头和代码状态的期望   方法或函数的执行结束,断言形成契约。   断言也可用于在运行时强制执行条件   为了防止在某些先决条件失败时执行。

答案 3 :(得分:5)

  

<强>前提

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

检查前进的必要条件。

  1. 使用此功能检测必须阻止程序的条件 甚至在运输代码中继续进行。
  2. 在playgrounds和-Onone构建中(Xcode&Debug。的默认值) 配置):如果condition的计算结果为false,则停止程序 打印消息后以可调试状态执行。
  3. 在-O内置(Xcode的默认配置发布配置):if condition计算结果为false,停止程序执行。
  4. 在-Ounchecked构建中,不评估条件,而是评估优化器 可以假设它会评估为真。不满足 在-Ounchecked构建中的假设是一个严重的编程错误。
  5.   

    <强>断言

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

    带有可选消息的传统C风格断言。

    1. 使用此功能进行内部健全检查 测试但不影响运输代码的性能。要检查 发布版本中的无效用法;见前提条件。

    2. 在playgrounds和-Onone构建中(Xcode&Debug。的默认值)     配置):如果condition的计算结果为false,则停止程序     在打印消息后以可调试状态执行。

    3. 在-O内置(Xcode的发布配置的默认设置),     条件未评估,并且没有影响
    4. 在-Ounchecked构建中,不评估条件,而是评估优化器     可以假设它会评估为真。不满足     在-Ounchecked构建中的假设是一个严肃的编程错误

答案 4 :(得分:0)

只想加我的2美分。您可以根据需要在代码中添加任意多个断言。您可以使用这些断言发送代码。 Swift不会为生产应用评估这些代码块。这些仅在调试模式下进行评估。

Adding documentation link

还附加了来自swift.org的图片

enter image description here

还请注意,前提条件并非如此。 前提条件附带的代码将崩溃,并且如果前提条件的评估结果不正确,则应用程序将终止。

因此,简而言之,断言用于调试,但可以在不影响生产的情况下进行传送。断言将在调试模式下进行评估,而不会在生产环境中进行评估。

前提条件用于确保生产环境中不会发生意外情况。这些条件将被评估,并在评估为假的情况下终止您的应用