您通常应该避免强行解开可选项(使用 operator !
),因为这将在可选项 contains 的情况下产生运行时异常nil
。下面遵循一些技术来处理选项的展开。
可选绑定
请注意,如果您将其解包并将其分配给另一个非可选变量到相同的固有类型,那么您可以“解包一次然后多次使用”的唯一方法。
这是使用可选绑定时所做的:
/* Example setup */
let display: UILabel = UILabel()
let digit = "1"
/* optional binding using if-let:
_assign_ unwrapped value (if non-nil) to 'unwrapped' */
if let unwrappedText = display.text {
// 'unwrapped' resides in scope inside of the if-let block
display.text = unwrappedText + digit
}
else {
display.text = digit
}
/* optional binding using guard-let-else:
_assign_ unwrapped value (if non-nil) to 'unwrapped' */
func foo(disp: UILabel, _ dig: String) {
guard let unwrappedText = display.text else {
display.text = digit
return
}
// 'unwrapped' resides in scope outside of the guard-let-else block
display.text = unwrappedText + digit
}
foo(display, digit)
无合并运算符
如果您不想使用条件绑定显式分配展开的值,则可以使用nil 合并运算符进行安全展开。
/* nil coalescing operator */
display.text = (display.text ?? "") + digit
但是,现在您可以以半可选绑定方式使用 nil 合并运算符;如果可选项为 nil,则分配可选项或某个默认值的展开值:
let metaUnwrapped = display.text ?? ""
不可变metaUnwrapped
将在其范围内可用,并包含display.text
(at assignment)nil
的值,如果不是,或者默认值""
,如果display.text
是nil
在分配。您可以在上面的可选绑定示例中以metaUnwrapped
与 immutable 相同的方式使用:unwrapped
display.text = metaUnwrapped + digit
可选链接
对于您的问题,这有点偏离基础,但是由于我们讨论的是可选和展开的主题,所以我不妨提一下可选链接。
鉴于可选属性不是 ,可选链接可用于访问某些可选属性的属性nil
。例如,假设您想计算 中的字符数display.text
,但自然只有当可选.text
属性为非时nil
。在这种情况下,可选链接与 nil 合并运算符相结合可能是一种合适的选择方法:
let numCharacters = display.text?.characters.count ?? 0
/* if text != nil, returns character count; otherwise, by
nil coalescing operator, returns 0 /*