iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Optionals

An optional is some(T) or none — Swift’s answer to null. The type system forces you to acknowledge nil before using the value. Force-unwrapping (!) is a crash waiting to happen.

Unwrap safely, chain, nil-coalesce

EXAMPLE
// 1) Declaring optionals
var name: String?         = nil           // explicit
var count: Int            = 0             // non-optional
// var x: String           = nil           // ERROR — non-optional can't be nil

// 2) if let — unwrap and bind
if let n = name {
    print("Hello, \\(n)")
} else {
    print("No name")
}

// 3) guard let — early exit (common in functions)
func greet(_ name: String?) {
    guard let name else {
        print("No one to greet")
        return
    }
    print("Hello, \\(name)")
}

// 4) Optional chaining — short-circuit nil through a chain
struct Address { var city: String? }
struct User    { var address: Address? }

let user: User? = User(address: Address(city: "Sydney"))
let city = user?.address?.city      // String? — Sydney
let len  = user?.address?.city?.count   // Int? — 6

// 5) Nil-coalescing — provide a default
let display = user?.address?.city ?? "Unknown"
let score   = scoreFromAPI ?? 0

// 6) Optional binding in conditions
if let user, let city = user.address?.city {
    print("\\(user.id) in \\(city)")
}

// 7) Optional pattern matching
let x: Int? = 7
switch x {
case .some(let v): print("got \\(v)")
case .none:        print("empty")
}
// Modern: switch x { case let v?: ... ; case nil: ... }

// 8) map / flatMap — transform without unwrapping
let len2 = name.map { $0.count }                // Int?
let first = words.first.flatMap { Int($0) }    // Int?, nil if word isn't a number

// 9) Force unwrap — ONLY when you're certain
let url = URL(string: "https://example.com")!   // crash if invalid
// Prefer:
guard let url = URL(string: someString) else { return }

// 10) Implicitly unwrapped — for late init that's guaranteed before use
//     (e.g. IBOutlets, dependency injected later)
@IBOutlet weak var label: UILabel!

// 11) Conditional cast — as? returns optional
if let user = obj as? User {
    print(user.name)
}

// 12) Multiple values
let first = name ?? email ?? "Anonymous"

// 13) Common bug — comparing to .some explicitly
if name != nil { ... }                      // works but Swift-y is `if let name`

// 14) Throwing alternative — when nil means "explain why"
enum ParseError: Error { case empty, badFormat }
func parseAge(_ s: String) throws -> Int {
    guard !s.isEmpty else { throw ParseError.empty }
    guard let n = Int(s) else { throw ParseError.badFormat }
    return n
}

Why it matters

Reach for guard let over if let in functions — it keeps the happy path un-indented and forces an early return for the nil case. Force-unwrap (!) only when failure should crash the app.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
var maybe: String? = nil
maybe = "Ada"
if let n = maybe {
    print("got \(n)")
}
let length = maybe?.count ?? 0
Try it Yourself »

Exercise

Default value when nil.

let len = name 0

Test yourself

Q1. Optionals model…
Q2. Default value for nil uses…
Q3. Force-unwrap an optional with…

Discussion

Loading…