Match
match tests one value against a sequence of patterns and runs whichever arm matches. It is both an expression and a statement, and the two forms share the same matching machinery and exhaustiveness checking. Every pattern form is on the Pattern page.
Basic Form
An arm has the shape pattern => body; arms are separated by commas, and a trailing comma on the last arm is optional. The body can be an expression, a block, or control flow starting with return / fail:
enum Shape
{
Circle(radius: float),
Rect(w: float, h: float),
Point,
}
func Area(s: Shape) -> float
{
return match s
{
Shape.Circle(r) => 3.14159 * r * r,
Shape.Rect(w, h) => w * h,
Shape.Point => 0.0,
};
}
print(Area(Shape.Circle(2.0)), Area(Shape.Rect(3.0, 4.0)), Area(Shape.Point));12.56636 12 0Shape.Circle(r) both tests the variant and deconstructs the payload into r.
when Guards
An arm can be followed by when condition for a second filter; the condition must produce a bool. Guards do not count toward exhaustive coverage:
func Describe(n: int) -> string
{
return match n
{
0 => "zero",
x when x < 0 => "negative",
x when x < 10 => "single digit",
_ => "two digits or more",
};
}
print(Describe(-5), Describe(0), Describe(7), Describe(42));negative zero single digit two digits or moreWhen a guarded arm matches, bindings from the arm-head pattern (here x) are available in the arm body.
Exhaustiveness Checking
match enforces exhaustiveness: every possible value must be handled by some arm, and a missing one raises MS4001, listing the uncovered cases. Guards and list patterns do not count as coverage; fall back to _:
error MS4001: match is not exhaustive: uncovered case(s) Point.A match statement gets the same exhaustiveness check; nobody consuming the result does not wave it through.
Arm Types Must Unify
In a match expression, all arm types must unify into one; mixing them raises MS3254:
error MS3254: match arm body types do not unify: 'string' vs 'int32'.When you need differently shaped results, make every arm produce the same type, such as string or tuple.
match as a Statement
Use the statement form when nobody consumes the result; arm bodies are usually side effects. The comma rules between arms are unchanged:
val n = 2;
match n
{
1 => print("one"),
2 => print("two"),
_ => print("many"),
}twoNotes
- Matching on error values shares one exhaustiveness accounting with
recoverconsumption; see Failure and Crash; - When the branch logic is flat (just comparing sizes), an if expression is lighter; reach for match when structure needs to be taken apart.
