【问题标题】:Difference between "precondition" and "assert" in swift?swift中“前提条件”和“断言”之间的区别?
【发布时间】:2015-06-22 18:14:06
【问题描述】:

precondition(condition: Bool, message: String)assert(condition: Bool, message: String) 在 Swift 中的区别是什么?

它们在我看来都一样。我们应该在哪种情况下使用一个而不是另一个?

【问题讨论】:

    标签: swift


    【解决方案1】:

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

    Adding documentation link

    另外附上来自 swift.org 的图片

    另请注意,前提条件并非如此。 如果未将先决条件评估为真,则附带先决条件的代码将崩溃并且应用程序将终止。

    简而言之,断言用于调试,但可以在不影响生产的情况下发布。断言将在调试模式下进行评估,而不是在生产中。

    前提条件是为了确保在生产环境中不会发生意外的事情。这些条件会被评估,并在被评估为错误时终止您的应用

    【讨论】:

      【解决方案2】:

      我发现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

      【讨论】:

      • 你能详细说明一下自己的代码和客户端的区别吗?至于客户,您的意思是在需要字符串的地方插入数字吗?不应该用一些简单的错误处理来处理吗?
      • @Honey 我认为他的意思是来自网络 API 调用或客户端自己的插件的参数/结果。
      • 客户将是使用您的代码的人,例如您正在编写一个库并且程序员传递了无效数据。你不想优雅地继续,因为这可能被认为是一个严重的编程错误。您可能永远不应该在无效的网络 API 数据上崩溃,因为这对用户没有帮助。
      • @onmyway133:从 Xcode QuickHelp 来看,我认为 precondition()preconditionFailure() 具有相同的行为。这些函数的不同之处在于:precondition 需要一个条件,而preconditionFailure 只是抛出。
      【解决方案3】:

      assert 用于测试期间的健全性检查,而precondition 用于防范如果发生,将意味着您的程序无法合理地继续进行。

      因此,例如,您可以将assert 放在一些具有合理结果的计算上(例如,在某些范围内),以便快速发现您是否有错误。但是您不想附带它,因为超出范围的结果可能是有效的,而且并不重要,因此不应使您的应用崩溃(假设您只是使用它来显示进度在进度条中)。

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

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

      前提条件

      检查前进的必要条件。

      使用此功能来检测必须阻止 即使在运输代码中,程序也不会继续进行。

      • 在 Playgrounds 和 -Onone 构建中(Xcode 调试的默认设置) 配置):如果condition 评估为假,则停止程序 打印message后以可调试状态执行。

      • 在 -O 构建中(Xcode 发布配置的默认设置): 如果condition 评估为假,则停止程序执行。

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

      断言

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

      将此功能用于激活的内部健全性检查 在测试期间,但不影响交付代码的性能。 检查发布版本中的无效使用;见precondition

      • 在 Playgrounds 和 -Onone 构建中(Xcode 调试的默认设置) 配置):如果condition 评估为假,则停止程序 打印message后以可调试状态执行。

      • 在 -O 构建中(Xcode 发布配置的默认设置), condition 未评估,也没有效果。

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

      【讨论】:

      • "但是你不会想附带那个,因为越界结果可能是有效的,而且不重要,所以不应该让你的应用崩溃"这对我来说很模糊。请您提供一个确切的例子吗?也许是一些代码。
      • 针对您的问题,我个人使用断言来捕获在我编写和测试它时不应该在我的构建中发生的事情。想象一个读取 JSON 的保护语句,其中 data["name"] 不存在,但它应该存在。在 guard..else{} 中有一个断言可以帮助我通过崩溃来捕获我的错误并将我带到问题中。同样,如果此代码在生产中,断言不会使程序崩溃,而我使用的任何备份代码 (return nil) 都会接管。
      • 你不应该检查索引而不做任何事情而不是让整个应用程序崩溃吗?
      • 是的,你应该检查索引,但有时每个人都会犯错,使用断言可以帮助你意识到你应该在忘记时检查索引。
      • “但你不会想附带那个,因为越界的结果可能是有效的,而且不重要,所以不应该让你的应用崩溃”。您可以根据需要使用任意数量的断言来发布您的应用程序。 Swift 只是不会在发布应用程序的断言块内评估您的条件
      【解决方案4】:

      前提条件

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

      检查前进的必要条件。

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

      断言

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

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

      1. 将此功能用于在运行期间处于活动状态的内部健全性检查 测试但不影响交付代码的性能。检查 发布版本中的无效使用;见前置条件。

      2. 在 Playground 和 -Onone 构建中(Xcode 调试的默认设置) 配置):如果条件评估为假,则停止程序 打印消息后以可调试状态执行。

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

      【讨论】:

        【解决方案5】:

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

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

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

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

        【讨论】:

        • 可以使用编译器标志启用和禁用断言;它们可以在交付的代码中处于活动状态。
        猜你喜欢
        • 2022-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-15
        • 1970-01-01
        • 2017-05-25
        • 1970-01-01
        • 2019-08-09
        相关资源
        最近更新 更多