Swift Optionals
Optionals are Swift's built-in way of saying a value might be missing, and the language forces you to handle that possibility before you can use it.
What Is an Optional?
In Swift, every type is non-optional by default, meaning a variable must always hold a real value of that type. An optional wraps a type to say 'this might hold a value of Int, or it might hold nothing at all.' You write an optional by appending a question mark to the type, such as Int? or String?. Under the hood, an optional is really an enum with two cases: .some(Value) or .none, but Swift gives you clean syntax so you rarely need to think about that directly.
Declaring Optional Types
Declaring and assigning optionals
var age: Int? = 25
var nickname: String? = nil
print(age) // Optional(25)
print(nickname) // nil
age = nilUnwrapping with if let
Because an optional might contain nothing, Swift won't let you use its value directly without unwrapping it first. The if let syntax, called optional binding, attempts to pull the value out; if it succeeds, a new non-optional constant is created and scoped to the if block. If the optional is nil, the else branch runs instead. This is the safest and most common way to react to an optional that may or may not have a value.
Unwrapping with if let
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
if let actualNumber = convertedNumber {
print("'\(possibleNumber)' converted to \(actualNumber)")
} else {
print("'\(possibleNumber)' could not be converted to an integer")
}
// Swift 5.7+ shorthand, reusing the same name:
// if let actualNumber { print(actualNumber) }Unwrapping with guard let and Early Exit
Unwrapping with guard let
func greet(person name: String?) {
guard let name = name else {
print("No name provided.")
return
}
// 'name' is a non-optional String from this point
// all the way to the end of the function.
print("Hello, \(name)!")
}
greet(person: "Ava") // Hello, Ava!
greet(person: nil) // No name provided.- Forced unwrapping (value!) — assumes a value exists and crashes at runtime if it's nil
- Optional binding (if let, guard let) — safely extracts the value into a new constant
- Nil-coalescing operator (??) — supplies a default value when the optional is nil
- Optional chaining (?.) — safely calls through a chain of optionals, short-circuiting to nil
Exercise: Swift Optionals
What happens if you force-unwrap (`!`) an optional that is currently `nil`?