Optional Chaining / map / flatMap (Optional)
Swift's Optional Chaining (?.) is a syntax for safely accessing properties and methods on an Optional — if the Optional is nil, the access is skipped and nil is returned instead.
Syntax
// Optional Chaining
optional?.property
optional?.method()
// Chained access (if any link is nil, the whole expression is nil)
optional?.propertyA?.propertyB
// Optional map / flatMap
optional.map { $0 + 1 } // nil if nil; otherwise transforms the value
optional.flatMap { Int($0) } // nil if nil or if the conversion fails
Syntax List
| Syntax | Description |
|---|---|
| opt?.property | Accesses property if opt is not nil; returns nil otherwise. |
| opt?.method() | Calls the method if opt is not nil. The return value is wrapped in an Optional. |
| opt?.a?.b?.c | Chains multiple Optionals. If any link in the chain is nil, the entire expression evaluates to nil. |
| opt.map { transform } | Returns nil if opt is nil; otherwise applies the transform and returns the result wrapped in an Optional. |
| opt.flatMap { transform } | Returns nil if opt is nil; avoids nesting when the transform itself returns an Optional. |
| opt.compactMap { transform } | Unwraps Optional elements in an array, returning a new array with nil values removed. |
Sample Code
// Basic Optional Chaining
class Address {
var city: String
init(city: String) { self.city = city }
}
class Person {
var name: String
var address: Address?
init(name: String, address: Address? = nil) {
self.name = name
self.address = address
}
}
let taro = Person(name: "Taro", address: Address(city: "Tokyo"))
let hanako = Person(name: "Hanako") // no address
// Safe access via Optional Chaining (nil-safe)
print(taro.address?.city ?? "Unknown") // Tokyo
print(hanako.address?.city ?? "Unknown") // Unknown
// Optional map
let optNumber: Int? = 5
let doubled = optNumber.map { $0 * 2 } // Optional(10)
let nilNumber: Int? = nil
let nilDoubled = nilNumber.map { $0 * 2 } // nil
print(doubled ?? 0) // 10
print(nilDoubled ?? 0) // 0
// flatMap (avoids nested Optionals)
let strNumber: String? = "42"
let parsed = strNumber.flatMap { Int($0) } // Optional(42)
let invalid: String? = "abc"
let failedParsed = invalid.flatMap { Int($0) } // nil
print(parsed ?? -1) // 42
print(failedParsed ?? -1) // -1
// compactMap on an array
let strings = ["1", "two", "3", "four", "5"]
let integers = strings.compactMap { Int($0) }
print(integers) // [1, 3, 5]
Overview
Optional Chaining (?.) lets you safely navigate complex object structures with multiple nested Optionals. If any link in the chain is nil, evaluation stops at that point and the entire expression returns nil.
map transforms the value inside an Optional and returns the result as an Optional. Use flatMap when the transform function itself returns an Optional — it flattens the result to avoid a nested Optional<Optional<T>>. Because Optional Chaining always produces an Optional, you must unwrap the result before using it.
For the basics of Optionals, see Optional / ? / !.
If you find any errors or copyright issues, please contact us.