如上所述,可选类型暗示了常量或者变量可以“没有值”。可选可以通过if
语句来判断是否有值,如果有值的话可以通过可选绑定来解析值。
有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型_总会_有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。
这种类型的可选状态被定义为隐式解析可选类型(implicitly unwrapped optionals)。把想要用作可选的类型的后面的问号(String?
)改成感叹号(String!
)来声明一个隐式解析可选类型。
当可选类型被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选类型非常有用。隐式解析可选类型主要被用在 Swift 中类的构造过程中,请参考无主引用以及隐式解析可选属性。
一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,并不需要每次都使用解析来获取可选值。下面的例子展示了可选类型String
和隐式解析可选类型String
之间的区别:
你可以把隐式解析可选类型当做一个可以自动解析的可选类型。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。
注意:
如果你在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选类型后面加一个惊叹号一样。
let possibleString: String? = "An optional string." let forcedString: String = possibleString! // 需要惊叹号来获取值 let assumedString: String! = "An implicitly unwrapped optional string." let implicitString: String = assumedString // 不需要感叹号
你可以使用错误处理(error handling)来应对程序执行中可能会遇到的错误条件。
相对于可选中运用值的存在与缺失来表达函数的成功与失败,错误处理可以推断失败的原因,并传播至程序的其他部分。
当一个函数遇到错误条件,它能报错。调用函数的地方能抛出错误消息并合理处理。
func makeASandwich() throws { // ... } do { try makeASandwich() eatASandwich() } catch Error.OutOfCleanDishes { washDishes() } catch Error.MissingIngredients(let ingredients) { buyGroceries(ingredients) }
在此例中,makeASandwich()
(做一个三明治)函数会抛出一个错误消息如果没有干净的盘子或者某个原料缺失。因为makeASandwich()
抛出错误,函数调用被包裹在try
表达式中。将函数包裹在一个do
语句中,任何被抛出的错误会被传播到提供的catch
从句中。
如果没有错误被抛出, eatASandwich()
函数会被调用。如果一个匹配Error.OutOfCleanDishes
的错误被抛出,washDishes
函数会被调用。如果一个匹配Error.MissingIngredients
的错误被抛出,buyGroceries(_:)
函数会随着被catch
所捕捉到的关联值[String]
被调用。
断言会在运行时判断一个逻辑条件是否为true
。从字面意思来说,断言“断言”一个条件是否为真。你可以使用断言来保证在运行其他代码之前,某些重要的条件已经被满足。如果条件判断为true
,代码运行会继续进行;如果条件判断为false
,代码执行结束,你的应用被终止。
如果你的代码在调试环境下触发了一个断言,比如你在 Xcode 中构建并运行一个应用,你可以清楚地看到不合法的状态发生在哪里并检查断言被触发时你的应用的状态。此外,断言允许你附加一条调试信息。
你可以使用全局assert(_:_:)
函数来写一个断言。向assert(_:_:)
函数传入一个结果为true
或者false
的表达式以及一条信息,当表达式的结果为false
的时候这条信息会被显示:
let age = -3 assert(age >= 0, "A person's age cannot be less than zero") // 因为 age < 0,所以断言会触发
在这个例子中,只有age >= 0
为true
的时候,即age
的值非负的时候,代码才会继续执行。如果age
的值是负数,就像代码中那样,age >= 0
为false
,断言被触发,终止应用。
如果不需要断言信息,可以省略,就像这样:
assert(age >= 0)