Pattern matching¶
Kod's match statement dispatches on a value and binds sub-parts.
Syntax¶
Arms are tested top-to-bottom. The first matching arm executes.
Pattern kinds¶
Catch-all (else)¶
else matches any value the other arms didn't cover. It must be the
last arm. The arrow is optional after else:
match x {
1 -> print("one")
2 -> print("two")
else -> print("other") // arrow form
}
match x {
1 -> print("one")
else { print("other") } // block form
}
Integer literal¶
String literal¶
Bool¶
Enum variant (explicit)¶
type Color = enum { Red, Green, Blue }
match c {
Color.Red -> print("red")
Color.Green -> print("green")
Color.Blue -> print("blue")
}
Enum variant (implicit shorthand)¶
When the type is clear from context, the enum name can be omitted:
Payload variant¶
Bind the payload fields:
type Shape = enum {
Circle(radius: int64)
Rect(w: int64, h: int64)
}
match shape {
Shape.Circle(radius) -> print_int(radius)
Shape.Rect(w, h) -> print_int(w * h)
}
Bindings are by position — the names in the pattern don't have to match the field names.
Optional¶
is test¶
A lightweight check without destructuring:
Match as expression¶
A match produces a value when every arm body is a single expression:
let label: str = match direction {
.North -> "north"
.South -> "south"
.East -> "east"
.West -> "west"
}
For multi-statement arm bodies, use a match statement and assign or return from inside.
if X is .Variant(bindings) { ... }¶
When you want a one-arm match with bindings in scope for the body, the
if/is sugar is shorter than a full match:
An optional else { ... } runs when the pattern doesn't match.
Pattern bindings stay scoped to the matching arm — they aren't
in scope in the else block.
let .Pattern(bindings) = expr else { ... }¶
Destructure with an early-exit on the non-matching case. The else
block must exit the enclosing scope (return / throw / panic) so the
bindings are guaranteed-in-scope below:
Exhaustiveness¶
A match on an enum (or on T? or bool) must cover every variant.
The compiler reports an error if any variant is missing and no
wildcard arm is present.
type Color = enum { Red, Green, Blue }
let c: Color = .Red
// error: match on Color doesn't cover variant Blue
match c {
.Red -> print("red")
.Green -> print("green")
}
Add the missing arm or an else catch-all:
The single-arm sugar (if X is .V(b) { ... } and let .V(b) = X else
{ ... }) is not subject to exhaustiveness — they're explicitly
one-variant checks.
A match on int64 or str must include an else arm — the
compiler reports an error otherwise. (int64 and str have too many
possible values to enumerate; the else makes the fall-through
explicit.)
Other limitations¶
- No nested patterns (e.g.
Shape.Rect(w, 0)matching on a specific field value) - No guard clauses (
ifconditions on arms)