More than two outcomes
An if/else chooses between two paths. When there are three or more cases, add else if branches between the if and the final else. Rust checks the conditions from top to bottom and runs the block of the first one that is true. After that, the rest of the chain is skipped, and no later condition is evaluated.
let language = "Python";
if language == "JavaScript" {
println!("It's super popular!");
} else if language == "Python" {
println!("It's so simple!");
} else if language == "Java" {
println!("It's pretty hardcore!");
} else {
println!("It's exotic!");
}
With language set to "Python", the first condition is false, so the chain moves on. The second is true, so the program prints It's so simple! and ignores the "Java" check. If language were "Go", every condition would be false and the final else would print It's exotic!.
The rules of a chain
- At most one block runs. With a final
else, exactly one block runs. Without it, none runs if every condition is false. - Order matters. A later branch runs only when every earlier condition was false, so each
else ifcan rely on what the earlier ones ruled out. This is what lets you write short conditions. - The
elsehas no condition and must come last. It catches everything the branches above did not. - Syntax. Rust conditions have no parentheses, the braces are required, and each condition must be a
bool. Writeelse ifas two words, noteliforelseif.
Order and ranges
Ranges are where the ordering helps most. Look at this chain on a number:
if grade < 5 {
println!("low");
} else if grade <= 7 {
println!("middle");
} else {
println!("high");
}
The second condition is only grade <= 7, not grade >= 5 && grade <= 7, because the first branch has already caught everything below 5. Written the other way round, the chain would be wrong: if you put grade <= 7 first, a grade of 3 would match it and print "middle". Always start with the most restrictive case, or reason about what each branch has already excluded.
An if chain is an expression
In Rust an if chain can produce a value. Write the value of each branch without a semicolon and every branch must have the same type:
let word = if grade < 5 { "low" } else if grade < 9 { "mid" } else { "high" };
Here word is "mid" when grade is 8. In this form the final else is required, because the expression needs a value on every path. If the branches have different types, such as "low" and 3, the compiler reports that the if and else have incompatible types. When you are matching one value against many patterns, a match is often tidier than a long chain, and the next lesson covers it.
Common mistakes
- Using separate
ifs instead ofelse if. Separateifstatements are all checked, so more than one block can run. - Wrong order. Broad conditions placed first hide the narrower ones below them.
- Off-by-one at the boundaries.
<and<=differ exactly at the border value. Decide which side each boundary value belongs to. - Using
=instead of==. A condition with a single=does not compile.
The lesson's exercise
The starter code defines let grade = 8;. The task is to print a message for each grade band.
- Start the chain with
if grade < 5and print"Failed the test". Failing grades are handled first. - Add
else if grade <= 7to print"Passed the test". Grades 5, 6 and 7 reach this branch, because lower grades were handled above. - Add
else if grade <= 9to print"Good Job", which covers 8 and 9. - Finish with an
elsethat prints"Perfect"for any grade above 9.
let grade = 8;
if grade < 5 {
println!("Failed the test");
} else if grade <= 7 {
println!("Passed the test");
} else if grade <= 9 {
println!("Good Job");
} else {
println!("Perfect");
}
For grade = 8, the first two conditions are false and the third is true, so the program prints Good Job. The other grades give: 3 prints Failed the test, 5 and 7 print Passed the test, 9 prints Good Job and 10 prints Perfect.
Key takeaways
else ifadds as many cases as you need; the first true condition wins.- Later branches only run when all earlier conditions were false, so order the checks deliberately.
- The final
elsetakes no condition and catches the rest. - An
ifchain can be an expression, and then every branch must have the same type and theelseis required.
