Patterns and Pattern Matching
Last Update: Swift 5
Pattern refers to “the structure of a single value or composite value”. Here are the list of patterns
Wildcard Pattern (Underscore)
This is what _
means. It matches and ignores any value.
for _ in 1...3 {
// do something three times
}
Identifier Pattern
This is the basic assignment pattern. let someValue = 42
is an example, someValue
is an identifier pattern that matches the value 42
of type Int
.
Value-Binding Pattern
Value-Binding is something on top fo identifier, it’s one of the first cases of pattern matching you might find, e.g.
let someTuple = (4, 5) // Tuple Pattern
switch someTuple {
case let (x, y): // Binds x and y to the elements of someTuple
// do something with x and y
break
}
Tuple Pattern
Refers to “a comma-separated list of zero or more patterns, enclosed in parentheses.” Note that parentheses around a single element are effectively ignored.
The following are valid example of Tuple Patterns:
let aTuple = (1, 2)
let (a, b) = (3, 4)
let (a) = 2 // Not a Tuple Pattern
Enumeration Case Pattern (Enum)
It matches the case of an existing enum type. They appear in switch
case labels, as well as if
, while
, guard
, and for-in
statements.
Using this enum:
enum AnEnum {
case foo
case bar
case baz
}
let myEnum = AnEnum.bar
switch statement:
switch myEnum {
case .foo:
// do something
break
case .bar:
break
default:
break
}
if statement:
if case .foo = myEnum {
// do something.
}
while statement:
while case .bar = myEnum {
// do something
}
guard statement:
guard case .baz = myEnum else {
return
}
Optional Pattern
This matches optional values. Uses the ?
syntax sugar to match things.
e.g.
let someOptional: Int? = 32
// Matches using enumeration case.
if case .some(let x) = someOptional {
// do something with x
}
// Matches using the optional pattern.
if case let x? = someOptional {
// do semithng with x
}
This also works with for-in, and switch statements:
for-in:
let arrayOfOptionals: [Int?] = [1, nil, 3, nil, 5]
for case let number? in arrayOfOptionalInts {
print("\(number)")
}
// prints "1", "3", "5"
switch:
let someOptional: Int? = 32
switch someOptional {
case 32?:
// something.
break
default:
// something else.
}
Type-Casting Patterns
This is the is
and as
patterns. is
is used as a conditional (if foo is Int
), or in switch statement case labels (case foo is Int: // do something with foo as an Int
). as
is used to change type to a related one, as needed (foo as String
).
Expression Pattern
This represents the value of an expression. These appear only in switch statement case labels.
e.g.:
let point = (1, 2)
switch point {
case (0, 0):
break
case (-2...2, -2...2):
break
default:
break
}
You can also overload the ~=
operator to provide a custom expression matching behavior.
func ~= (pattern: String, value: Int) -> Bool {
return pattern == "\(value)"
}
switch 3 {
case "3":
print("This actually matches")
default:
break
}
Last updated: 2019-07-06 11:39:54 -0700