You should generally avoid to forcibly unwrap optionals (with operator !
), as this will yield a runtime exception in case the optional contains nil
. Below follows some techniques to handle unwrapping of optionals.
Optional binding
Note that the only way you can "unwrap it once and then use it multiple times" if if you unwrap and assign it to another non-optional variable to the same inherent type.
This is what is done when using optional binding:
/* 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 coalescing operator
If you don't want to explicitly assign the unwrapped value using conditional binding, you can make use of the nil coalescing operator for safe unwrapping.
/* nil coalescing operator */
display.text = (display.text ?? "") + digit
Now, you could, however, use the nil coalescing operator in a semi-optional-binding fashion; assign the unwrapped value of an optional or some default value if the optional is nil:
let metaUnwrapped = display.text ?? ""
Immutable metaUnwrapped
would be available in its scope, and contain the value of display.text
(at assignment), if non-nil
, or the default value ""
, if display.text
was nil
at assignment. You could use metaUnwrapped
in the same fashion as immutable unwrapped
in the optional binding examples above:
display.text = metaUnwrapped + digit
Optional chaining
This is slightly off-base w.r.t. your question, but since we're on the subject of optionals and unwrapping, I might as well mention optional chaining.
Optional chaining can be used to access properties of some optional property, given that the optional property is not nil
. As an example, say you want to count the number of characters in the display.text
, but naturally only if the optional .text
property is non-nil
. In this case, optional chaining combined with the nil coalescing operator could be a proper method of choice:
let numCharacters = display.text?.characters.count ?? 0
/* if text != nil, returns character count; otherwise, by
nil coalescing operator, returns 0 /*