Swift Language Unwrapping an Optional


Example

In order to access the value of an Optional, it needs to be unwrapped.

You can conditionally unwrap an Optional using optional binding and force unwrap an Optional using the ! operator.

Conditionally unwrapping effectively asks "Does this variable have a value?" while force unwrapping says "This variable has a value!".

If you force unwrap a variable that is nil, your program will throw an unexpectedly found nil while unwrapping an optional exception and crash, so you need to consider carefully if using ! is appropriate.

var text: String? = nil
var unwrapped: String = text! //crashes with "unexpectedly found nil while unwrapping an Optional value"

For safe unwrapping, you can use an if-let statement, which will not throw an exception or crash if the wrapped value is nil:

var number: Int?
if let unwrappedNumber = number {       // Has `number` been assigned a value?
    print("number: \(unwrappedNumber)") // Will not enter this line
} else {
    print("number was not assigned a value")
}

Or, a guard statement:

var number: Int?
guard let unwrappedNumber = number else {
    return
}
print("number: \(unwrappedNumber)")

Note that the scope of the unwrappedNumber variable is inside the if-let statement and outside of the guard block.

You can chain unwrapping of many optionals, this is mainly useful in cases that your code requires more then variable to run correctly:

var firstName:String?
var lastName:String?

if let fn = firstName, let ln = lastName {
    print("\(fn) + \(ln)")//pay attention that the condition will be true only if both optionals are not nil.
}

Note that all the variables have to be unwrapped in order to pass successfully the test, otherwise you would have no way to determine which variables were unwrapped and which weren't.

You can chain conditional statements using your optionals immediately after it is unwrapped. This means no nested if - else statements!

var firstName:String? = "Bob"
var myBool:Bool? = false

if let fn = firstName, fn == "Bob", let bool = myBool, !bool {
    print("firstName is bob and myBool was false!")
}