We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Shape Your Data: Structs, Enums, Pattern Matching step 13 of 26
Grade scores with match guards
Repair the match expression in the supplied grading function. Keep the subject-specific threshold and use a final unguarded arm to cover the remaining scores.
pub fn grade(scores: Vec<(String, i64)>) -> Vec<String>
Return one "<subject>:<verdict>" string per input pair, in the same order.
Preserve each subject exactly, including its case and whitespace.
| Subject | Pass mark |
|---|---|
Exactly "maths" |
70 |
Exactly "art" |
50 |
| Any other string | 60 |
A negative score is invalid. A nonnegative score at or above the pass mark
is pass; a lower score is fail. Scores can span the full i64 range, so
values above 100 are valid and pass. An empty input returns an empty vector.
For example, ("maths", 69) produces "maths:fail", while ("Maths", 69)
produces "Maths:pass": the capitalized name uses the default threshold.
("art", -1) produces "art:invalid".
Compare against a runtime value
The required variable is computed from the subject. You cannot use that
local variable as a range-pattern endpoint such as required..; those
endpoints must be permitted compile-time constants. A guard lets you compare
a matched value with required:
fn verdict(score: i64, required: i64) -> &'static str {
match score {
points if points >= required => "pass",
_ => "fail",
}
}
fn main() {
assert_eq!(verdict(70, 70), "pass");
assert_eq!(verdict(69, 70), "fail");
}
A guard runs after its pattern matches and can use the pattern's bindings.
When a guard fails, matching continues. Rust chooses the first arm whose
pattern and guard succeed. In this exercise, handle negative scores before
the fallback so they are reported as invalid rather than fail.
A guard attached to an or-pattern applies to every alternative. For
Some(1) | Some(2) if enabled, both alternatives require enabled.
Split them into separate arms if they need different conditions.
Why the starter is not exhaustive
The starter's three guards logically cover every score, but Rust does not
use guards to establish exhaustiveness. Even a guard written as if true
does not make its arm count as unconditional coverage. The starter therefore
fails with E0004.
Keep the negative and passing cases, then replace the final guarded case
with _ => "fail". The wildcard needs no condition: earlier arms have
already handled the other verdicts. It also gives the compiler an unguarded
pattern that covers every remaining value.
Guards are useful for relationships a pattern cannot express, such as a
comparison with this local threshold. When a fixed value or range expresses
the condition directly, a pattern may be clearer. For example, Some(5)
expresses the same match as Some(x) if x == 5 without a guard.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.