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!")
}