Pattern matching is one of the best features of any programming language as it allows to design rules that match values against each other. This simplifies and provides flexibility to the code. Pattern matching is made available in Swift by Apple.
A wild card pattern matches and ignores any value and it comprises of an underscore(_). A
wildcard pattern is used when a developer does not care much of the values that are asserted
to match. For example, the below-written code returns through a closed range, 1….3,
disregarding the current value of the range on each return of the loop.
An Identifier Pattern matches any value and attaches that matched value to a constant name or variable. For example, in the below constant declaration, “someValue” is considered as an identifier pattern that matches value 42 that is of integer type.
When the above-determined match succeeds, the value 42 is assigned to the constant name “someValue”. When the left side pattern of a variable or a constant declaration is redeemed as an identifier pattern, it is implicitly considered as a sub-pattern of a value-binding pattern.
A value-binding pattern gets attached its values to a variable or constant name. It binds a matched value to the name of a constant and begins it with the “let” keyword; that binds it to the name of a variable and starts it with a “var” keyword. It identifies patterns through a value-binding pattern to bind a new named variable or constant to its matching values. For example,
we can fragment such elements of a tuple and bind the value of each element to its corresponding identifier patterns.
A tuple pattern is separated with a comma in the list of zero or within more patterns, placed in parentheses. It matches the values of corresponding tuple types. We can compel a tuple pattern to match certain kinds of tuple types by using 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 the elements are of integer type. When it is used in a for-in statement or a variable or in a constant declaration then, this may also consist of wildcard patterns, identifier patterns, optional patterns, and various functions of tuple patterns.
An enumeration case pattern matches the case of the present enumeration type. It comes forth in a switch statement case labels and into the case conditions of if, while, guard, and for-in statements.
If it has similar associated values then, it must clarify a tuple pattern that consists of one element for each associated value. For example, it will use a switch statement to match enumeration cases that may consist of other associated values.
The optional pattern matches its values wrapped in some(Wrapped) case of an Optional<Wrapped> enumeration. It consists of an identifier pattern followed by a question mark and is managed in the same places as enumeration case patterns. Because Optional patterns are derived according to the syntax for Optional enumeration case patterns.
Type-Casting patterns vary in two of its types— “is” pattern and “as” pattern. The “is” pattern appears in “switch” statement case labels. It matches a value only if the type of that value in run time is the same as the type of value specified on the right side of that pattern or a subclass. If this applied match succeeds, then the type of matched value is cast to the pattern value that is specified on the right side of the “as” pattern.
The expression pattern constitutes a value of an expression. This pattern only appears in “switch” statement class labels. It is represented by an expression that is compared through an input expression with the use of the Swift standard library~= operator. Its match succeeds only if the ~= operator returns a “true” value. It is by default compared with the values of ~= operator of the same type using == operator. It matches a range of values by checking whether a value is obtained within that range.
Pattern matching in swift with its various pattern matching techniques forms to be an extremely strong concept which offers us with more options in terms of syntax we use to implement things like loops, conditionals, and switch statements—but it also allows us to reduce code paths and build our logic to be more declarative, that often leads to more robust code that is easier to test.