match compares one value against an ordered set of patterns. It is useful when an if chain would repeat the same comparison many times.
text {
let number = 13;
match number {
1 => "One!",
2 | 3 | 5 | 7 | 11 | 13 => "This is a prime",
13..=19 => "A teen",
_ => "Not special",
}
}
Sugar checks the arms from top to bottom. The first matching arm wins, so 13 produces "This is a prime" before Sugar reaches the teen range.
Return a value
match is an expression. Its selected arm becomes its value:
let binary = match damaged {
false => 0,
true => 1,
};
The same value form can initialize a variable or constant:
const growthStage = match growth {
0..=99 => 1,
100..=199 => 2,
200..=299 => 3,
_ => 4,
};
A match can also appear inside a larger expression. Its arms remain lazy, so Sugar evaluates only the selected result:
const reward = if score < 0 then 0 else match rank {
"BRONZE" => 10,
"SILVER" => 20,
"GOLD" => 40,
_ => 0,
};
It can also be the final expression of a program:
match mood {
"HAPPY" => "@1 is glowing today!",
"TIRED" => "@1 needs a quiet moment.",
_ => "@1 is taking the day as it comes.",
}
The value after match is evaluated once. A subject such as Rand::pick(1..=100) rolls once and compares that one result with every arm.
Combine patterns
Use | when several patterns should share one result:
match roll {
1 | 2 | 3 => "Low roll",
4 | 5 => "Good roll",
6 => "Perfect roll!",
_ => "Unexpected roll",
}
Match number ranges
Number patterns use the same range rules as the rest of Sugar:
match score {
0..50 => "Below 50",
50..=89 => "Passing",
90..=100 => "Excellent",
_ => "Outside the expected score",
}
0..50 includes 0 through 49. 50..=89 includes both 50 and 89.
Match several values together
Put values in a list when one decision depends on their combination. Then use a fixed-list pattern with the same shape:
match ($species, $personality) {
("SULCATA", "CURIOUS") => "CURIOUS",
("SULCATA", "DETERMINED") => "RESTLESS",
("SULCATA", _) => "RELAXED",
("WOLF", "PLAYFUL") => "PLAYFUL",
("WOLF", _) => "CALM",
_ => "NONE",
}
("SULCATA", _) means a two-entry list whose first value is "SULCATA"; _ accepts any second value. It does not match a one-entry or three-entry list because fixed-list patterns require the exact same length.
Each position can use the patterns you already know, including alternatives and ranges:
match ($species, $age) {
("SULCATA" | "WOLF", 0..=2) => "YOUNG",
(_, 3..=10) => "GROWN",
_ => "OTHER",
}
Patterns may also be nested when the subject contains nested lists. Structural matching checks values; it does not create variables or unpack the list. As with every match, Sugar checks arms from top to bottom and uses the first match.
Run several instructions
Put braces after => when an arm needs a full program. This complete Boop Code module declares the shared values and performs one roll:
var health = 100;
var xp = 0;
text {
let roll = Rand::pick(1..=100);
match roll {
1 => {
health -= 10;
"Critical failure!"
},
100 => {
xp += 20;
"Perfect roll!"
},
_ => format("You rolled {roll}"),
}
}
Only the selected arm runs. Its final expression supplies the value of the match.
Cover every possible value
_ matches anything not handled earlier and must be the last arm. Sugar normally requires it so the match always produces a value.
A boolean match is already complete when it contains both true and false:
match enabled {
true => "Enabled",
false => "Disabled",
}
Match patterns can be numbers, strings, booleans, None, number ranges, fixed lists containing other patterns, alternatives joined with |, or _.
The next lesson introduces complete Item action declarations. Memory variables follow once there is an action that can change them.