断言和先决条件
This commit is contained in:
@ -16,8 +16,8 @@
|
||||
> 校对:[SketchK](https://github.com/SketchK)
|
||||
>
|
||||
> 3.0
|
||||
> 校对:[CMB](https://github.com/chenmingbiao),版本时间2016-09-13
|
||||
>
|
||||
> 校对:[CMB](https://github.com/chenmingbiao),版本时间2016-09-13
|
||||
>
|
||||
> 3.0.1, 2016-11-11,shanks
|
||||
|
||||
本页包含内容:
|
||||
@ -48,7 +48,7 @@
|
||||
- [可选绑定](#optional_binding)
|
||||
- [隐式解析可选类型](#implicityly_unwrapped_optionals)
|
||||
- [错误处理](#error_handling)
|
||||
- [断言](#assertions)
|
||||
- [断言和先决条件](#assertions_and_Preconditions)
|
||||
|
||||
Swift 是一门开发 iOS, macOS, watchOS 和 tvOS 应用的新语言。然而,如果你有 C 或者 Objective-C 开发经验的话,你会发现 Swift 的很多内容都是你熟悉的。
|
||||
|
||||
@ -772,17 +772,21 @@ do {
|
||||
|
||||
抛出,捕捉,以及传播错误会在[错误处理](./18_Error_Handling.html)章节详细说明。
|
||||
|
||||
<a name="assertions"></a>
|
||||
## 断言
|
||||
<a name="assertions_and_Preconditions"></a>
|
||||
## 断言和先决条件
|
||||
|
||||
可选类型可以让你判断值是否存在,你可以在代码中优雅地处理值缺失的情况。然而,在某些情况下,如果值缺失或者值并不满足特定的条件,你的代码可能没办法继续执行。这时,你可以在你的代码中触发一个 *断言(assertion)* 来结束代码运行并通过调试来找到值缺失的原因。
|
||||
断言和先决条件是在运行时所做的检查。你可以用他们来检查在执行后续代码之前是否一个必要的条件已经被满足了。如果断言或者先决条件中的布尔条件评估的结果为 true(真),则代码像往常一样继续执行。如果布尔条件评估结果为false(假),程序的当前状态是无效的,则代码执行结束,应用程序中止。
|
||||
|
||||
你使用断言和先决条件来表达你所做的假设和你在编码时候的期望。你可以将这些包含在你的代码中。断言帮助你在开发阶段找到错误和不正确的假设,先决条件帮助你在生产环境中探测到存在的问题。
|
||||
|
||||
除了在运行时验证你的期望值,断言和先决条件也变成了一个在你的代码中的有用的文档形式。和在上面讨论过的[错误处理](./18_Error_Handling.html)不同,断言和先决条件并不是用来处理可以恢复的或者可预期的错误。因为一个断言失败表明了程序正处于一个无效的状态,没有办法去捕获一个失败的断言。
|
||||
|
||||
使用断言和先决条件不是一个能够避免出现程序出现无效状态的编码方法。然而,如果一个无效状态程序产生了,断言和先决条件可以强制检查你的数据和程序状态,使得你的程序可预测的中止(译者:不是系统强制的,被动的中止),并帮助使这个问题更容易调试。一旦探测到无效的状态,执行则被中止,防止无效的状态导致的进一步对于系统的伤害。
|
||||
|
||||
断言和先决条件的不同点是,他们什么时候进行状态检测:断言仅在调试环境运行,而先决条件则在调试环境和生产环境中运行。在生产环境中,断言的条件将不会进行评估。这个意味着你可以使用很多断言在你的开发阶段,但是这些断言在生产环境中不会产生任何影响。
|
||||
|
||||
### 使用断言进行调试
|
||||
|
||||
断言会在运行时判断一个逻辑条件是否为 `true`。从字面意思来说,断言“断言”一个条件是否为真。你可以使用断言来保证在运行其他代码之前,某些重要的条件已经被满足。如果条件判断为 `true`,代码运行会继续进行;如果条件判断为 `false`,代码执行结束,你的应用被终止。
|
||||
|
||||
如果你的代码在调试环境下触发了一个断言,比如你在 Xcode 中构建并运行一个应用,你可以清楚地看到不合法的状态发生在哪里并检查断言被触发时你的应用的状态。此外,断言允许你附加一条调试信息。
|
||||
|
||||
你可以使用全局 `assert(_:_:file:line:)` 函数来写一个断言。向这个函数传入一个结果为 `true` 或者 `false` 的表达式以及一条信息,当表达式的结果为 `false` 的时候这条信息会被显示:
|
||||
|
||||
```swift
|
||||
@ -797,20 +801,33 @@ assert(age >= 0, "A person's age cannot be less than zero")
|
||||
|
||||
```swift
|
||||
assert(age >= 0)
|
||||
```
|
||||
|
||||
如果代码已经检查了条件,你可以使用 `assertionFailure(_:file:line:)`函数来表明断言失败了,例如:
|
||||
|
||||
```swift
|
||||
if age > 10 {
|
||||
print("You can ride the roller-coaster or the ferris wheel.")
|
||||
} else if age > 0 {
|
||||
print("You can ride the ferris wheel.")
|
||||
} else {
|
||||
assertionFailure("A person's age can't be less than zero.")
|
||||
}
|
||||
```
|
||||
|
||||
> 注意:
|
||||
> 当代码使用优化编译的时候,断言将会被禁用,例如在 Xcode 中,使用默认的 target Release 配置选项来 build 时,断言会被禁用。
|
||||
### 强制执行先决条件
|
||||
|
||||
### 何时使用断言
|
||||
当一个条件可能为false(假),但是继续执行代码要求条件必须为true(真)的时候,需要使用先决条件。例如使用先决条件来检查是否下标越界,或者来检查是否将一个正确的参数传给函数。
|
||||
|
||||
当条件可能为假时使用断言,但是最终一定要_保证_条件为真,这样你的代码才能继续运行。断言的适用情景:
|
||||
你可以使用全局 `precondition(_:_:file:line:)` 函数来写一个先决条件。向这个函数传入一个结果为 `true` 或者 `false` 的表达式以及一条信息,当表达式的结果为 `false` 的时候这条信息会被显示:
|
||||
|
||||
* 整数类型的下标索引被传入一个自定义下标实现,但是下标索引值可能太小或者太大。
|
||||
* 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。
|
||||
* 一个可选值现在是 `nil`,但是后面的代码运行需要一个非 `nil` 值。
|
||||
```swift
|
||||
// In the implementation of a subscript...
|
||||
precondition(index > 0, "Index must be greater than zero.")
|
||||
```
|
||||
|
||||
请参考[下标](./12_Subscripts.html)和[函数](./06_Functions.html)。
|
||||
你可以调用 `precondition(_:_:file:line:)`方法来表明出现了一个错误,例如,switch进入了default分支,但是所有的有效值应该被任意一个其他分支(非default分支)处理。
|
||||
|
||||
> 注意:
|
||||
> 断言可能导致你的应用终止运行,所以你应当仔细设计你的代码来让非法条件不会出现。然而,在你的应用发布之前,有时候非法条件可能出现,这时使用断言可以快速发现问题。
|
||||
> 如果你使用unchecked模式(-Ounchecked)编译代码,先决条件将不会进行检查。编译器假设所有的先决条件总是为true(真),他将优化你的代码。然而,`fatalError(_:file:line:)`函数总是中断执行,无论你怎么进行优化设定。
|
||||
>你能使用 `fatalError(_:file:line:)`函数在设计原型和早期开发阶段,这个阶段只有方法的声明,但是没有具体实现,你可以在方法体中写上fatalError("Unimplemented")作为具体实现。因为fatalError不会像断言和先决条件那样被优化掉,所以你可以确保当代码执行到一个没有被实现的方法时,程序会被中断。
|
||||
Reference in New Issue
Block a user