Optionals are Swift's answer to null pointer crashes, and nearly every API returns or accepts them.
A normal Swift type can never be nil. To allow absence, use an optional: String? means "a String or nothing". Under the hood it is the enum Optional<Wrapped> with cases .some(value) and .none.
You can't use an optional as if it were the value; you must unwrap it:
if let name { ... }— binds a non-optionalnameinside the block (shorthand forif let name = name).guard let user else { return }— unwraps for the rest of the scope.value ?? fallback— the nil-coalescing operator supplies a default.user?.address?.city— optional chaining; the whole expression becomesnilas soon as any link isnil.optional.map { ... }transforms the value if present.
The force unwrap value! crashes if the value is nil. Reserve it for cases where nil would be a programmer error, and prefer a descriptive guard with fatalError or preconditionFailure when you do.
Many APIs return optionals to signal failure without an error: Int("42") is Int?, and array.first is nil for an empty array. Implicitly unwrapped optionals (String!) exist mostly for interop and Interface Builder outlets; avoid them in new code.
Example
func greet(_ input: String?) -> String {
guard let input, !input.isEmpty else { return "Hello, stranger" }
return "Hello, \(input)"
}
print(greet(nil)) // Hello, stranger
print(greet("Mia")) // Hello, Mia
let port = Int("8080") ?? 80 // 8080
let bad = Int("abc") ?? 80 // 80
struct User { var nickname: String? }
let u: User? = User(nickname: nil)
print(u?.nickname?.count as Any) // nil
if let n = Int("12") {
print(n * 2) // 24
}Remember
T?can be nil; plainTnever is- Unwrap with
if let,guard let,??or?. !crashes on nil — use it only for true invariants
Watch out for
- Sprinkling
!to silence the compiler; it moves the crash to run time.