@match
@match compares a value against a list of patterns and runs the first arm
that matches.
Syntax
@match value {
pattern => { ... }
pattern => { ... }
_ => { ... }
}
Arms are tried from top to bottom. _ matches anything. If no arm matches,
nothing happens. Commas between arms are optional.
Matching values
A pattern that’s an ordinary expression matches if it equals the value:
macro name_length(n: int) {
@match n {
0 => { @emit 4 } # "zero"
1 => { @emit 3 } # "one"
1 + 1 => { @emit 3 } # "two"
_ => { @emit -1 }
}
}
name_length 0
name_length 2
name_length 7
4 3 -1
Matching enums
Matching is most useful with enums. Name a variant by itself, or qualified by its enum:
enum Color {
Red,
Green,
Blue,
}
macro code(c: Color) {
@match c {
Red => { @emit 1 }
Color.Green => { @emit 2 }
_ => { @emit 3 }
}
}
code Color.Red
code Color.Green
code Color.Blue
1 2 3
For a variant with a payload, Variant(name) binds the payload to name for
that arm. Variant(_) matches any payload without binding it.
enum Shape {
Circle: int,
Square: int,
Empty,
}
macro area(s: Shape) {
@match s {
Shape.Circle(r) => { @emit 3 * r * r }
Square(w) => { @emit w * w }
Empty => { @emit 0 }
}
}
area Shape.Circle(2)
area Shape.Square(5)
area Shape.Empty
12 25 0
Variant(expression), where the expression isn’t a plain name, matches only
when the payload equals it. Qualified forms work the same way:
Shape.Circle(r), and for a generic enum, Option<int>.Some(v).
A pattern that isn’t a variant, such as a constant holding an enum value, is
compared with ==:
enum Color {
Red,
Green,
Blue,
}
const FAVORITE = Color.Blue
macro is_favorite(c: Color) {
@match c {
FAVORITE => { @emit 1 }
_ => { @emit 0 }
}
}
is_favorite Color.Blue
is_favorite Color.Red
1 0
Returning from a match
@return inside an arm returns from the whole macro:
from std.option import Option
macro unwrap_or(o: Option<int>, fallback: int) -> int {
@match o {
Option<int>.Some(v) => { @return v }
None => { @return fallback }
}
}
macro show(value: int) {
@emit value
}
show unwrap_or(Option<int>.Some(42), 0)
show unwrap_or(Option<int>.None, 7)
42 7