【发布时间】:2015-06-22 18:14:06
【问题描述】:
precondition(condition: Bool, message: String) 和 assert(condition: Bool, message: String) 在 Swift 中的区别是什么?
它们在我看来都一样。我们应该在哪种情况下使用一个而不是另一个?
【问题讨论】:
标签: swift
precondition(condition: Bool, message: String) 和 assert(condition: Bool, message: String) 在 Swift 中的区别是什么?
它们在我看来都一样。我们应该在哪种情况下使用一个而不是另一个?
【问题讨论】:
标签: swift
只是想加我的 2 美分。您可以根据需要在代码中添加任意数量的断言。您可以使用这些断言发送您的代码。 Swift 不会为生产应用评估这些代码块。这些仅在调试模式下进行评估。
另外附上来自 swift.org 的图片
另请注意,前提条件并非如此。 如果未将先决条件评估为真,则附带先决条件的代码将崩溃并且应用程序将终止。
简而言之,断言用于调试,但可以在不影响生产的情况下发布。断言将在调试模式下进行评估,而不是在生产中。
和
前提条件是为了确保在生产环境中不会发生意外的事情。这些条件会被评估,并在被评估为错误时终止您的应用
【讨论】:
我发现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
【讨论】:
precondition() 和 preconditionFailure() 具有相同的行为。这些函数的不同之处在于:precondition 需要一个条件,而preconditionFailure 只是抛出。
assert 用于测试期间的健全性检查,而precondition 用于防范如果发生,将意味着您的程序无法合理地继续进行。
因此,例如,您可以将assert 放在一些具有合理结果的计算上(例如,在某些范围内),以便快速发现您是否有错误。但是您不想附带它,因为超出范围的结果可能是有效的,而且并不重要,因此不应使您的应用崩溃(假设您只是使用它来显示进度在进度条中)。
另一方面,在获取元素时检查数组上的下标是否有效是precondition。当请求一个无效的下标时,数组对象没有合理的下一步操作,因为它必须返回一个非可选值。
来自文档的全文(尝试在 Xcode 中单击选项并单击 assert 和 precondition):
前提条件
检查前进的必要条件。
使用此功能来检测必须阻止 即使在运输代码中,程序也不会继续进行。
在 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 构建中的假设是一个严重的问题 编程错误。
【讨论】:
data["name"] 不存在,但它应该存在。在 guard..else{} 中有一个断言可以帮助我通过崩溃来捕获我的错误并将我带到问题中。同样,如果此代码在生产中,断言不会使程序崩溃,而我使用的任何备份代码 (return nil) 都会接管。
前提条件
func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
检查前进的必要条件。
断言
func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
带有可选消息的传统 C 样式断言。
将此功能用于在运行期间处于活动状态的内部健全性检查 测试但不影响交付代码的性能。检查 发布版本中的无效使用;见前置条件。
在 Playground 和 -Onone 构建中(Xcode 调试的默认设置) 配置):如果条件评估为假,则停止程序 打印消息后以可调试状态执行。
【讨论】:
precondition 在发布模式下处于活动状态,因此当您发布应用且前提条件失败时,应用将终止。
Assert 默认只在调试模式下工作。
当在 NSHipster 上使用它时,我发现了这个很好的解释:
断言是从经典逻辑中借来的概念。在逻辑上, 断言是关于证明中的命题的陈述。在 编程,断言表示程序员所做的假设 申报地点的申请情况。
当用于前置条件和后置条件的容量时, 在开头描述对代码状态的期望和 方法或函数执行结束,断言形成合约。 断言也可用于在运行时强制执行条件,在 为了在某些先决条件失败时阻止执行。
【讨论】: