Pattern matching in Swift allows you to elegantly extract values and compare them against patterns in switch conditions, loops, and if case statements. A key feature is not only the ability to compare values but also to extract associated data from complex structures, such as enumerations with associated values, optionals, or tuples.
The case let operator is often used to extract nested values, for example:
enum Result { case success(value: Int) case failure(error: Error) } let result: Result = .success(value: 42) switch result { case .success(let value): print("Success with value \(value)") case .failure(let error): print("Failed with error: \(error)") }
It is also convenient to use pattern matching when working with collections:
let items: [Result] = [.success(value: 1), .failure(error: MyError()), .success(value: 42)] for case let .success(value) in items { print("Found value: \(value)") }
It is important to remember that not all patterns will work if the structure or enum is defined without associated values or without the necessary Equatable support. Also, inexperienced developers may make mistakes with exhaustiveness (completeness of handling all cases of an enum).
What is the difference between if let, guard let, and if case let when working with optional values? In which cases is each preferable?
Answer:
if let and guard let are used for safely unwrapping values from optionals.if case let applies not only to optionals but also to enums with associated values, extending the capabilities of pattern matching.Example:
let number: Int? = 42 if case let value? = number { print("Value is \(value)") }
value? is a pattern that extracts the value only if it is not nil.
Story
A developer did not implement all cases for an enum in a switch. Adding a new case to the enum led to a silent error, as a default branch was added "for reliability." As a result, part of the logic stopped working, and the error only manifested to the user.
Story
The project used an array
Result<T, Error>and attempted to filter only successful values through a regularfor x in...loop. This led to manual type checking, causing some successes to be missed due to an error in the condition.
Story
One team member was unaware of
if case letwith optionals and always performed a double check: firstif number != nil, then forced unwrapping. This led to crashes in production.