Pattern Matching
Pattern matching overview
Pattern matching allows for either simple quality checks, or for creating a combination of member equality checks, member captures, and member ‘ignores’ for tuples and enum values in switches and case expressions.
Tuple pattern matching
void TupleCaseExpr()
{
let tup = (1.2, "Abc");
// This performs one equality check and one member capture
if (tup case (1.2, let str))
{
UseStr(str);
}
}
void TupleSwitch()
{
let tup = (x: 10, y: 20, str:"Abc");
switch (tup)
{
case (0, 0, let drawStr):
DrawAtOrigin(drawStr);
case (var drawX, var drawY, let drawStr):
/* Since drawX and drawY are 'var' the are mutable, whereas drawStr is immutable */
drawX += 10;
drawY += 20;
Draw(x, y, drawStr);
}
}
Enum pattern matching
enum Shape
{
case Rectangle(int x, int y, int width, int height);
case Circle(int x, int y, int radius);
}
void EnumCase()
{
Shape shape = .Circle(10, 20, 30);
/* One enum discriminator check, two member equality checks, and one member captures */
if (shape case .Circle(0, 0, let radius))
{
DrawCircleAtOrigin(radius);
}
/* One enum discriminator check, and three member captures */
else if (shape case .Circle(let x, let y, let radius))
{
DrawCircle(x, y, radius);
}
/* One enum discriminator check, and two member captures, one member ignore */
else if (shape case .Circle(let x, let y, ?))
{
DrawPoint(x, y);
}
/* Enum discriminator check, no member checks or captures*/
if (shape case .Rectangle)
{
IgnoreRectangle();
}
}
/* This is equivalent to the EnumCase method */
void EnumSwitch()
{
Shape shape = .Circle(10, 20, 30);
switch (shape)
{
case .Circle(0, 0, let radius):
DrawCircleAtOrigin(radius);
case .Circle(let x, let y, let radius):
DrawCircle(x, y, radius);
case .Rectangle:
IgnoreRectangle();
}
}
Enums can also pattern match to a ‘ref’, allowing modification of the underlying values.
void Enlarge(ref Shape shape)
{
switch (shape)
{
case .Circle(?, ?, var ref radius):
radius++;
case .Rectangle(?, ?, var ref width, var ref height):
width++;
height++;
}
}