Pattern
A pattern is a description of a value’s shape. match arms, if val, while val, expect, for iteration variables, and destructuring bindings all share one pattern machinery; this page lists all of it in one place.
Forms at a Glance
| Form | Name | Description |
|---|---|---|
_ | wildcard | Matches anything, binds nothing |
name | binding | Always matches; binds an immutable value |
val name / var name | explicit binding | Declares read-only / mutable respectively |
42 -42 3.14 "lit" 'c' true null | literal | Must agree with the scrutinee’s category |
1..=10 | range | lo..hi half-open, lo..=hi closed; one bound may be omitted |
A | B | or | Each alternative must have the same binding set (MS4005) |
A & B | and | Both patterns must match |
Type(p1, p2) | type (positional payload) | Tests the type and deconstructs by position |
Type { field: p, field2, .. } | type (named payload) | The shorthand field2 equals field2: field2; .. ignores the remaining fields |
name @ pattern | sub-binding | Binds the whole value to name while matching the inner pattern |
(p1, p2) | tuple | Deconstructs by position |
[a, b] | list (prefix) | The length must match exactly |
[x, ..rest] | list (rest) | rest binds a copied array of the remaining elements |
[x, ..] / [..] / [] | list (ignore / any / empty) | See below |
Pkg::Mod.Type(...) | qualified type | A type qualified within the same package or across packages |
{ kind: 1, hp: h, .. } | anonymous record | The scrutinee must be a data value (MS3271) |
Literals, Ranges, and Or
for n in [5, 42, 95, 300]
{
print(n, match n
{
5 | 42 => "the answer or five",
90..=100 => "ninety-plus tier",
v @ 101..=299 => $"middle band {v}",
_ => "the rest",
});
}5 the answer or five
42 the answer or five
95 ninety-plus tier
300 the restv @ 101..=299 binds the whole value into v while requiring it to fall inside the range. Neither side of an or pattern may carry bindings (or each side must carry exactly the same binding set); otherwise it raises MS4005.
Tuples
val pair = (1, "a");
match pair
{
(n, s) => print($"number {n}: {s}"),
}
val (m, tag) = pair;
print(m, tag);number 1: a
1 aThe destructuring binding val (a, b) = expr is a pattern’s first application outside match: the left side of the equals sign is a pattern.
Tuple values on the any channel support type-shape checks: if e is (int, string) p decides at runtime by component count plus per-element recursion, binding the tuple value to p on a hit, while a shape mismatch quietly yields False. Nested shapes and nullable elements take part too ((int?, string) matches a null).
var e: any = (1, "a");
if e is (int, string) p
{
print(p.Item1);
}aList Patterns
The scrutinee must be a list<T> or an array. A prefix pattern requires the length to match exactly; ..rest binds the remaining elements as a copied array; a lone .. means “ignore everything after this point”; [] matches only the empty list:
func Classify(xs: list<int>) -> string
{
return match xs
{
[] => "empty list",
[only] => $"single element {only}",
[a, b] => $"a pair {a} and {b}",
[first, ..rest] => $"first {first}, plus {rest.Count} more",
_ => "fallback",
};
}
print(Classify(new list<int>()));
print(Classify([7]));
print(Classify([1, 2]));
print(Classify([1, 5, 9, 12]));empty list
single element 7
a pair 1 and 2
first 1, plus 3 morerestis an independent copied array: binding copies the remaining elements, writes torest[i]change only the copy, the original list is unaffected, and later mutation of the original list is not reflected in rest...may appear only in the last element position; the middle form[a, .., b]is not supported.- Nested list patterns (
[[a], ..]) are legal. - List patterns never count toward exhaustiveness:
[..]looks like it matches any list, but the exhaustiveness check gives it no coverage; match still needs a_fallback.
Destructuring bindings accept list patterns too:
val xs = [10, 20, 30, 40];
val [head, ..tail] = xs;
print(head, tail);10 [20, 30, 40]Notes
- A literal pattern whose category differs from the scrutinee’s raises MS4002 (matching
"x"ortrueagainst an int value, say); integer literals do adapt to floats. - Float literal patterns ignore suffixes:
0.3,0.3f32, and0.3f16are judged the same, compared after rounding to the scrutinee’s width. - The iteration-variable slot of
foris a pattern slot;for (k, v) in pairsdestructures directly.
