---
title: Patterns
framework: swift-book
role: article
path: swift-book/ReferenceManual/Patterns
---

# Patterns

Match and destructure values.

## Wildcard Pattern

A *wildcard pattern* matches and ignores any value and consists of an underscore (`_`). Use a wildcard pattern when you don't care about the values being matched against. For example, the following code iterates through the closed range `1...3`, ignoring the current value of the range on each iteration of the loop:

```swift for _ in 1...3 {     // Do something three times. } ```

<!--   - test: `wildcard-pattern`

```swifttest   -> for _ in 1...3 {         // Do something three times.      }   ``` -->

> Grammar of a wildcard pattern: > > *wildcard-pattern* → **`_`**

## Identifier Pattern

An *identifier pattern* matches any value and binds the matched value to a variable or constant name. For example, in the following constant declaration, `someValue` is an identifier pattern that matches the value `42` of type `Int`:

```swift let someValue = 42 ```

<!--   - test: `identifier-pattern`

```swifttest   -> let someValue = 42   ``` -->

When the match succeeds, the value `42` is bound (assigned) to the constant name `someValue`.

When the pattern on the left-hand side of a variable or constant declaration is an identifier pattern, the identifier pattern is implicitly a subpattern of a value-binding pattern.

> Grammar of an identifier pattern: > > *identifier-pattern* → *identifier*

## Value-Binding Pattern

A *value-binding pattern* binds matched values to variable or constant names. Value-binding patterns that bind a matched value to the name of a constant begin with the `let` keyword; those that bind to the name of variable begin with the `var` keyword.

Identifiers patterns within a value-binding pattern bind new named variables or constants to their matching values. For example, you can decompose the elements of a tuple and bind the value of each element to a corresponding identifier pattern.

```swift let point = (3, 2) switch point { // Bind x and y to the elements of point. case let (x, y):     print("The point is at (\(x), \(y)).") } // Prints "The point is at (3, 2)." ```

<!--   - test: `value-binding-pattern`

```swifttest   -> let point = (3, 2)   -> switch point {         // Bind x and y to the elements of point.         case let (x, y):            print("The point is at (\(x), \(y)).")      }   <- The point is at (3, 2).   ``` -->

In the example above, `let` distributes to each identifier pattern in the tuple pattern `(x, y)`. Because of this behavior, the `switch` cases `case let (x, y):` and `case (let x, let y):` match the same values.

> Grammar of a value-binding pattern: > > *value-binding-pattern* → **`var`** *pattern* | **`let`** *pattern*

<!--   NOTE: We chose to call this "value-binding pattern"   instead of "variable pattern",   because it's a pattern that binds values to either variables or constants,   not a pattern that varies.   "Variable pattern" is ambiguous between those two meanings. -->

## Tuple Pattern

A *tuple pattern* is a comma-separated list of zero or more patterns, enclosed in parentheses. Tuple patterns match values of corresponding tuple types.

You can constrain a tuple pattern to match certain kinds of tuple types by using type annotations. For example, the tuple pattern `(x, y): (Int, Int)` in the constant declaration `let (x, y): (Int, Int) = (1, 2)` matches only tuple types in which both elements are of type `Int`.

When a tuple pattern is used as the pattern in a `for`-`in` statement or in a variable or constant declaration, it can contain only wildcard patterns, identifier patterns, optional patterns, or other tuple patterns that contain those. For example, the following code isn't valid because the element `0` in the tuple pattern `(x, 0)` is an expression pattern:

```swift let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] // This code isn't valid. for (x, 0) in points {     /* ... */ } ```

<!--   - test: `tuple-pattern`

```swifttest   -> let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]   -> // This code isn't valid.   -> for (x, 0) in points {   >>    _ = x         /* ... */      }   !$ error: expected pattern   !! for (x, 0) in points {   !!         ^   ``` -->

The parentheses around a tuple pattern that contains a single element have no effect. The pattern matches values of that single element's type. For example, the following are equivalent:

<!--   This test needs to be compiled.   The error message in the REPL is unpredictable as of   Swift version 1.1 (swift-600.0.54.20) -->

```swift let a = 2        // a: Int = 2 let (a) = 2      // a: Int = 2 let (a): Int = 2 // a: Int = 2 ```

<!--   - test: `single-element-tuple-pattern`

```swifttest   -> let a = 2        // a: Int = 2   -> let (a) = 2      // a: Int = 2   -> let (a): Int = 2 // a: Int = 2   !$ error: invalid redeclaration of 'a'   !! let (a) = 2      // a: Int = 2   !! ^   !$ note: 'a' previously declared here   !! let a = 2        // a: Int = 2   !! ^   !$ error: invalid redeclaration of 'a'   !! let (a): Int = 2 // a: Int = 2   !! ^   !$ note: 'a' previously declared here   !! let a = 2        // a: Int = 2   !! ^   ``` -->

> Grammar of a tuple pattern: > > *tuple-pattern* → **`(`** *tuple-pattern-element-list*_?_ **`)`** \ > *tuple-pattern-element-list* → *tuple-pattern-element* | *tuple-pattern-element* **`,`** *tuple-pattern-element-list* \ > *tuple-pattern-element* → *pattern* | *identifier* **`:`** *pattern*

## Enumeration Case Pattern

An *enumeration case pattern* matches a case of an existing enumeration type. Enumeration case patterns appear in `switch` statement case labels and in the case conditions of `if`, `while`, `guard`, and `for`-`in` statements.

If the enumeration case you're trying to match has any associated values, the corresponding enumeration case pattern must specify a tuple pattern that contains one element for each associated value. For an example that uses a `switch` statement to match enumeration cases containing associated values, see <doc:Enumerations#Associated-Values>.

An enumeration case pattern also matches values of that case wrapped in an optional. This simplified syntax lets you omit an optional pattern. Note that, because `Optional` is implemented as an enumeration, `.none` and `.some` can appear in the same switch as the cases of the enumeration type.

```swift enum SomeEnum { case left, right } let x: SomeEnum? = .left switch x { case .left:     print("Turn left") case .right:     print("Turn right") case nil:     print("Keep going straight") } // Prints "Turn left". ```

<!--   - test: `enum-pattern-matching-optional`

```swifttest   -> enum SomeEnum { case left, right }   -> let x: SomeEnum? = .left   -> switch x {      case .left:          print("Turn left")      case .right:          print("Turn right")      case nil:          print("Keep going straight")      }   <- Turn left   ``` -->

> Grammar of an enumeration case pattern: > > *enum-case-pattern* → *type-identifier*_?_ **`.`** *enum-case-name* *tuple-pattern*_?_

## Optional Pattern

An *optional pattern* matches values wrapped in a `some(Wrapped)` case of an `Optional<Wrapped>` enumeration. Optional patterns consist of an identifier pattern followed immediately by a question mark and appear in the same places as enumeration case patterns.

Because optional patterns are syntactic sugar for `Optional` enumeration case patterns, the following are equivalent:

```swift let someOptional: Int? = 42 // Match using an enumeration case pattern. if case .some(let x) = someOptional {     print(x) }

// Match using an optional pattern. if case let x? = someOptional {     print(x) } ```

<!--   - test: `optional-pattern`

```swifttest   -> let someOptional: Int? = 42   -> // Match using an enumeration case pattern.   -> if case .some(let x) = someOptional {         print(x)      }   << 42

-> // Match using an optional pattern.   -> if case let x? = someOptional {         print(x)      }   << 42   ``` -->

The optional pattern provides a convenient way to iterate over an array of optional values in a `for`-`in` statement, executing the body of the loop only for non-`nil` elements.

```swift let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5] // Match only non-nil values. for case let number? in arrayOfOptionalInts {     print("Found a \(number)") } // Found a 2 // Found a 3 // Found a 5 ```

<!--   - test: `optional-pattern-for-in`

```swifttest   -> let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]   -> // Match only non-nil values.   -> for case let number? in arrayOfOptionalInts {         print("Found a \(number)")      }   </ Found a 2   </ Found a 3   </ Found a 5   ``` -->

> Grammar of an optional pattern: > > *optional-pattern* → *identifier-pattern* **`?`**

## Type-Casting Patterns

There are two type-casting patterns, the `is` pattern and the `as` pattern. The `is` pattern appears only in `switch` statement case labels. The `is` and `as` patterns have the following form:

```swift is <#type#> <#pattern#> as <#type#> ```

The `is` pattern matches a value if the type of that value at runtime is the same as the type specified in the right-hand side of the `is` pattern --- or a subclass of that type. The `is` pattern behaves like the `is` operator in that they both perform a type cast but discard the returned type.

The `as` pattern matches a value if the type of that value at runtime is the same as the type specified in the right-hand side of the `as` pattern --- or a subclass of that type. If the match succeeds, the type of the matched value is cast to the *pattern* specified in the right-hand side of the `as` pattern.

For an example that uses a `switch` statement to match values with `is` and `as` patterns, see <doc:TypeCasting#Type-Casting-for-Any-and-AnyObject>.

> Grammar of a type casting pattern: > > *type-casting-pattern* → *is-pattern* | *as-pattern* \ > *is-pattern* → **`is`** *type* \ > *as-pattern* → *pattern* **`as`** *type*

## Expression Pattern

An *expression pattern* represents the value of an expression. Expression patterns appear only in `switch` statement case labels.

The expression represented by the expression pattern is compared with the value of an input expression using the pattern-matching operator (`~=`) from the Swift standard library. The matches succeeds if the `~=` operator returns `true`. By default, the `~=` operator compares two values of the same type using the `==` operator. It can also match a value with a range of values, by checking whether the value is contained within the range, as the following example shows.

```swift let point = (1, 2) switch point { case (0, 0):     print("(0, 0) is at the origin.") case (-2...2, -2...2):     print("(\(point.0), \(point.1)) is near the origin.") default:     print("The point is at (\(point.0), \(point.1)).") } // Prints "(1, 2) is near the origin." ```

<!--   - test: `expression-pattern`

```swifttest   -> let point = (1, 2)   -> switch point {         case (0, 0):            print("(0, 0) is at the origin.")         case (-2...2, -2...2):            print("(\(point.0), \(point.1)) is near the origin.")         default:            print("The point is at (\(point.0), \(point.1)).")      }   <- (1, 2) is near the origin.   ``` -->

You can overload the `~=` operator to provide custom expression matching behavior. For example, you can rewrite the above example to compare the `point` expression with a string representations of points.

```swift // Overload the ~= operator to match a string with an integer. func ~= (pattern: String, value: Int) -> Bool {     return pattern == "\(value)" } switch point { case ("0", "0"):     print("(0, 0) is at the origin.") default:     print("The point is at (\(point.0), \(point.1)).") } // Prints "The point is at (1, 2)." ```

<!--   - test: `expression-pattern`

```swifttest   -> // Overload the ~= operator to match a string with an integer.   -> func ~= (pattern: String, value: Int) -> Bool {         return pattern == "\(value)"      }   -> switch point {         case ("0", "0"):            print("(0, 0) is at the origin.")         default:            print("The point is at (\(point.0), \(point.1)).")      }   <- The point is at (1, 2).   ``` -->

> Grammar of an expression pattern: > > *expression-pattern* → *expression*

<!-- This source file is part of the Swift.org open source project

Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -->
