if, else if, else — and if as an expression
An if in Rust looks like the one you know, with two differences. The condition needs no parentheses, and it must be a real bool — Rust never treats 0, an empty string or a missing value as false. The braces around each branch are always required, even for one line.
fn main() {
let temperature = 31;
if temperature > 30 {
println!("hot");
} else if temperature > 15 {
println!("mild");
} else {
println!("cold");
}
let items = 3;
if items != 0 { // say what you mean: != 0
println!("cart has {items} items");
}
}hot
cart has 3 itemsE0308: an integer is not a bool
fn main() {
let items = 3;
if items {
println!("cart is not empty");
}
}error[E0308]: mismatched types
--> main.rs:3:8
|
3 | if items {
| ^^^^^ expected `bool`, found integerC, JavaScript and Python quietly treat a non-zero number as true. Rust has no "truthy" values: the condition of an if must have type bool, so an integer is a type mismatch.
Write the comparison you actually mean: items != 0 or items > 0.
fn main() {
let items = 3;
if items > 0 {
println!("cart is not empty");
}
}if produces a value
In Rust almost everything is an expression — something that evaluates to a value. An if/else is one of them: the value of the whole thing is the value of the branch that ran. That replaces the ternary operator (cond ? a : b), which Rust does not have.
fn main() {
let score = 72;
let grade = if score >= 90 {
'A'
} else if score >= 70 {
'B'
} else {
'C'
}; // the let still ends with ;
println!("grade {grade}");
let stock = 0;
let label = if stock > 0 { "in stock" } else { "sold out" };
println!("{label}");
}grade B
sold outDelete the final else branch from grade and compile. The compiler says an if without else evaluates to () — why can that never be a char?
E0308: if and else have incompatible types
fn main() {
let in_stock = true;
let label = if in_stock { 5 } else { "sold out" };
println!("{label}");
}error[E0308]: `if` and `else` have incompatible types
--> main.rs:3:42
|
3 | let label = if in_stock { 5 } else { "sold out" };
| - ^^^^^^^^^^ expected integer, found `&str`
| |
| expected because of thisA variable has exactly one type, fixed at compile time. If one branch gives an integer and the other a string slice, the compiler cannot say what type label is, so every branch of an if used as a value must produce the same type.
Make both branches return the same type. Here both should be text.
fn main() {
let in_stock = true;
let label = if in_stock { "5 left" } else { "sold out" };
println!("{label}");
}