Nil-Coalescing and Optional Chaining
Providing fallback values with ?? and safely reaching into nested optionals with ?.
読了時間 2 分
if let and guard let handle most optional-unwrapping needs, but two more operators cover the cases where you just want a default value, or need to safely dig into a chain of optional properties.
The nil-coalescing operator: ??
?? provides a fallback value to use when an optional is nil, in a single expression:
let storedName: String? = nil
let displayName = storedName ?? "Guest"
print(displayName) // "Guest"
let savedScore: Int? = 87
let score = savedScore ?? 0
print(score) // 87 — the optional had a value, so the fallback is unusedThis replaces what would otherwise be a multi-line if let/else just to supply a default:
// Without ??
let name: String
if let storedName {
name = storedName
} else {
name = "Guest"
}
// With ??
let name = storedName ?? "Guest"?? can also chain, trying each optional in turn until one has a value:
let userSetting: String? = nil
let systemDefault: String? = nil
let fallback = "en-US"
let locale = userSetting ?? systemDefault ?? fallback // "en-US"Optional chaining: ?.
When you need to access a property or call a method on something that might be nil, optional chaining lets you do it in one step — if any link in the chain is nil, the whole expression short-circuits to nil instead of crashing.
struct Address {
let city: String
}
struct Person {
let name: String
let address: Address?
}
let person = Person(name: "Sam", address: nil)
let city = person.address?.city // City? — nil, because address is nil
print(city ?? "Unknown city") // "Unknown city"person.address?.city reads as "if address exists, get its city; otherwise, the whole expression is nil." Without the ?, accessing .city on a nil address would be a compile error (or a crash, if force-unwrapped) — optional chaining makes "reach in if it's there" a normal, safe operation.
Combining both
?? and ?. are frequently used together — chain safely into a nested structure, then supply a fallback for the final result:
let cityName = person.address?.city ?? "Unknown city"This single line replaces what would otherwise be a guard let/if let just to read one nested, possibly-missing value — and it's idiomatic Swift you'll see constantly once you start reading real codebases. Between if let, guard let, ??, and ?., you now have the full toolkit for working with optionals safely.