Swift Tip: Unwrapping Optionals
When we use the !
operator to force-unwrap an optional value in Swift Talk, we sometimes hear from viewers that it would be better not to use force-unwrapping. However, while we try to be very careful about force-unwrapping an optional value, it's mostly a very deliberate choice if we do force-unwrap. The key questions we ask ourselves in these cases is: does the nil
value occur due to a programmer error?
Consider the example of creating an URL from a static string like this:
let url: URL? = URL(string: "https://www.objc.io")
The URL initializer is failable, because not every string represents a valid URL:
let url: URL? = URL(string: "🤔")
assert(url == nil)
However, if we create a URL from a static string, it's the programmer's responsibility to specify a valid URL. A string that results in a nil
value is like a typo or a logic error in your code. Therefore we force-unwrap the result to crash immediately in case we've made a mistake:
let url: URL = URL(string: "https://www.objc.io")!
If you use force-unwrapping like this carefully, you can read the !
character in your code as an assertion. It signifies a check for the correctness of your code.
We encountered a similar, though less obvious example when writing a concurrent map function in Swift Talk 90:
extension Array {
func concurrentMap<B>(_ transform: @escaping (Element) -> B) -> [B] {
var result = Array<B?>(repeating: nil, count: count)
let q = DispatchQueue(label: "sync queue")
DispatchQueue.concurrentPerform(iterations: count) { idx in
let element = self[idx]
let transformed = transform(element)
q.sync {
result[idx] = transformed
}
}
return result.map { $0! }
}
}
At the very end of the function, we map over the result array and force unwrap all the values. We could have avoided the force-unwrap by using flatMap
instead of map
, but this would only serve to mask potential programming errors. The result array must contain the same number of elements as the original array, i.e. there must not be a nil
value in it. If there is, we have made a mistake and should crash immediately.
We talk much more about handling optionals in Swift Talk 93: besides force-unwrapping, we look at API design with optionals, optional chaining, implicitly-unwrapped optionals and more.
Subscribe to access all our episodes.