Swift Expression Pattern
In Swift pattern matching, an expression pattern matches against values by evaluating an expression. This powerful feature allows you to compare values against expressions in switch
statements and other pattern-matching contexts. In this lesson, we'll explore how expression patterns work and how they can make your code more elegant and concise.
Introduction to Expression Patterns
An expression pattern represents a value that can be compared with the input value using Swift's pattern matching operator (~=
). This allows you to match against values in creative and flexible ways.
Expression patterns are particularly useful when:
- You need to match against computed values
- You want to check if a value falls within a range
- You're implementing custom pattern matching behavior
Basic Expression Pattern Usage
Let's start with a simple example of an expression pattern in a switch
statement:
let value = 42
switch value {
case 0:
print("Zero")
case 1...50:
print("Between 1 and 50")
case 100:
print("One hundred")
default:
print("Some other value")
}
Output:
Between 1 and 50
In this example, 1...50
is an expression pattern that represents a range. The ~=
operator is used implicitly to check if value
is contained within this range.
How the Pattern Matching Operator Works
Behind the scenes, Swift uses the ~=
operator for pattern matching. This operator is defined for many standard types, and you can also overload it for custom types.
The basic form is:
pattern ~= value
For example, with a range:
let matchResult = (1...50) ~= 42 // true
print(matchResult)
Output:
true
Common Expression Patterns
Range Patterns
Range patterns are among the most commonly used expression patterns:
let score = 85
switch score {
case 0..<60:
print("Failed")
case 60..<70:
print("D grade")
case 70..<80:
print("C grade")
case 80..<90:
print("B grade")
case 90...100:
print("A grade")
default:
print("Invalid score")
}
Output:
B grade
Type Casting Patterns
You can use the is
and as
patterns to check and cast types:
let item: Any = "Hello, Swift!"
switch item {
case is String:
print("This is a string")
case is Int:
print("This is an integer")
case let number as Double:
print("This is a double with value: \(number)")
default:
print("Unknown type")
}
Output:
This is a string
Function Call Expressions
You can use function calls in expression patterns:
func isEven(_ number: Int) -> Bool {
return number % 2 == 0
}
let number = 24
switch number {
case let x where isEven(x):
print("\(x) is even")
default:
print("\(number) is odd")
}
Output:
24 is even
Custom Pattern Matching with ~=
One of the most powerful features of expression patterns is the ability to customize the ~=
operator for your own types:
struct Temperature {
let celsius: Double
init(celsius: Double) {
self.celsius = celsius
}
var fahrenheit: Double {
return celsius * 9/5 + 32
}
}
// Define a custom pattern matching operator
func ~= (pattern: Range<Double>, value: Temperature) -> Bool {
return pattern.contains(value.celsius)
}
let currentTemperature = Temperature(celsius: 23)
switch currentTemperature {
case -10..<0:
print("Below freezing")
case 0..<15:
print("Cool weather")
case 15..<25:
print("Pleasant weather")
case 25..<35:
print("Hot weather")
default:
print("Extreme temperature")
}
Output:
Pleasant weather
Using Expression Patterns in if-case Statements
Expression patterns aren't limited to switch
statements. You can also use them in if case
and guard case
statements:
let optionalNumber: Int? = 42
// Using if-case with expression pattern
if case 30...50 = optionalNumber ?? 0 {
print("Number is between 30 and 50")
}
// Using guard-case with expression pattern
func processNumber(_ number: Int?) {
guard case 1...100 = number ?? -1 else {
print("Number is out of valid range")
return
}
print("Processing valid number: \(number!)")
}
processNumber(42)
processNumber(101)
Output:
Number is between 30 and 50
Processing valid number: 42
Number is out of valid range
Real-world Application: Weather App
Here's a practical example showing how expression patterns could be used in a weather application:
struct WeatherData {
let temperature: Double // in Celsius
let windSpeed: Double // in km/h
let precipitation: Double // in mm
let uvIndex: Int // 0-11 scale
}
func getWeatherWarning(for weather: WeatherData) -> String {
switch weather {
case let w where w.temperature > 35:
return "🔥 Extreme heat warning! Stay hydrated and avoid direct sun."
case let w where w.temperature < -10:
return "❄️ Extreme cold warning! Dress warmly and limit outdoor exposure."
case let w where w.windSpeed > 60:
return "💨 High wind warning! Secure loose items outdoors."
case let w where w.precipitation > 25:
return "🌧️ Heavy rain warning! Be aware of potential flooding."
case let w where w.uvIndex > 8:
return "☀️ High UV warning! Use sunscreen and wear protective clothing."
default:
return "No severe weather warnings."
}
}
let todaysWeather = WeatherData(temperature: 37, windSpeed: 15, precipitation: 0, uvIndex: 9)
print(getWeatherWarning(for: todaysWeather))
Output:
🔥 Extreme heat warning! Stay hydrated and avoid direct sun.
Summary
Expression patterns are a flexible and powerful feature in Swift's pattern matching system. They allow you to:
- Match against ranges, types, and computed values
- Customize pattern matching behavior with the
~=
operator - Use pattern matching in
switch
,if case
, andguard case
statements - Create more readable and expressive code for complex conditions
By mastering expression patterns, you can write more concise, readable, and maintainable code that clearly expresses your intent.
Exercises
-
Write a function that uses pattern matching to categorize students by their grades (A: 90-100, B: 80-89, C: 70-79, D: 60-69, F: below 60).
-
Create a custom
~=
operator for aUser
struct that allows matching users by age ranges. -
Implement a simple calculator that uses pattern matching to interpret basic arithmetic expressions.
-
Extend the weather example to include multiple warnings in a single message when multiple conditions are met.
Additional Resources
- Swift Documentation on Pattern Matching
- WWDC Session: What's New in Swift
- Swift Evolution: Pattern Matching
Happy coding with Swift expression patterns!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)