Chapter 12: Rust If .. Else
Rust If .. Else — one of the most fundamental ways to make decisions in code.
In Rust, we call them if expressions (not just statements) because they can return values — that’s a very nice Rust feature compared to many other languages. I’ll explain everything slowly like your personal teacher sitting next to you with VS Code open: basic syntax, chaining, else if, if as expression, common patterns, and even the related if let and let else (which are super useful in real Rust code).
Let’s go step by step with examples you can copy-paste right now.
1. Basic if – No Parentheses Needed!
Rust’s if is clean — no mandatory () around the condition, and the condition must be a bool (no automatic conversion from int like in C or JavaScript).
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
fn main() { let temperature = 35; if temperature > 32 { println!("It's hot in Hyderabad today! 🔥"); } // No else — that's fine, just skip if false } |
Run → if condition true → prints message. If false → nothing happens.
2. Adding else
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
fn main() { let temperature = 28; if temperature > 32 { println!("Summer mode ON ☀️🔥"); } else { println!("Nice weather for learning Rust! 🦀"); } } |
- else block runs when condition is false
- Both blocks are {} — even single line needs them (no dangling else ambiguity)
3. Chaining with else if (Multiple Conditions)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
fn main() { let temp = 38; if temp > 40 { println!("Extreme heat warning! Stay indoors 😓"); } else if temp > 35 { println!("Very hot — AC full power! ❄️"); } else if temp > 30 { println!("Typical Hyderabad summer ☀️"); } else { println!("Pleasant day — go for a walk 🌳"); } } |
- Checked from top to bottom
- Only first true block runs
- Final else (optional) catches everything else
4. if is an Expression — It Can Return a Value!
This is huge — if can be used on the right side of let, like a ternary operator but more powerful and readable.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
fn main() { let temp = 33; let advice = if temp > 32 { "Drink lots of water and stay in shade!" } else { "Perfect weather — enjoy the day!" }; println!("Temperature: {}°C → {}", temp, advice); } |
- All branches must return the same type (or compatible)
- Last expression in each block is the value (no ; needed if it’s the return)
Example with numbers:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
fn main() { let number = 7; let description = if number < 5 { "small" } else if number < 10 { "medium" } else { "large" }; println!("{} is {}", number, description); // 7 is medium } |
5. if let – Pattern Matching in if (Very Common & Clean)
if let combines if + let for when you only care about one pattern (usually Some / Ok / specific enum variant).
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
fn main() { let optional_number = Some(42); if let Some(value) = optional_number { println!("Got a number: {}", value); } else { println!("No number :("); } // Classic real-world example let coin = Some("Quarter(Telangana)"); if let Some(state) = coin { println!("Found coin from {}", state); } } |
- Shorter than full match when you ignore most cases
- Can chain else if let too (but less common)
6. let else – The Modern Way (Rust 1.65+ — Very Useful 2026)
Introduced later — lets you bind variables or diverge (return/panic/break) early if pattern fails.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
fn main() { let text = "42 chairs"; let Ok(number) = text.parse::<u32>() else { println!("Not a number!"); return; // or panic!, break, continue, etc. }; println!("Parsed number: {}", number); // only runs if parse succeeds } |
- let else binds if match succeeds
- else block must diverge (never returns normally) — compiler enforces this
- Cleaner than old match or if let + return
Real example (file reading style):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
use std::fs::File; fn open_config() -> Result<File, std::io::Error> { let file = File::open("config.toml") else { return Err(std::io::Error::new(std::io::ErrorKind::NotFound, "config missing")); }; Ok(file) } |
7. Quick Tips & Common Mistakes (Teacher Warnings)
- No () around condition → if temperature > 32 (not if (temperature > 32))
- Braces {} always required — even for one line
- All branches same type when used as expression
- Prefer if let / let else over deep match when only one case matters
- For many conditions → match often cleaner than long else if chain
Full Small Project Example to Try
Create cargo new rust_if_else and put in main.rs:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
fn main() { let hour = 14; // 2 PM in 24-hour format let greeting = if hour < 12 { "Good morning! ☕" } else if hour < 17 { "Good afternoon! 🌞" } else { "Good evening! 🌙" }; println!("Time: {}:00 → {}", hour, greeting); // if let example let maybe_temp: Option<i32> = Some(36); if let Some(temp) = maybe_temp { let comfort = if temp > 32 { "hot" } else { "nice" }; println!("Temperature: {}°C → feels {}", temp, comfort); } else { println!("No temperature reading"); } // let else example let input = "100"; let Ok(value) = input.parse::<i32>() else { println!("Invalid number!"); return; }; println!("Parsed successfully: {}", value); } |
Run cargo run — play with changing hour, maybe_temp, input values.
Summary in Teacher Voice
Rust if .. else = powerful decision making:
- Basic if {} / else {} / else if {}
- No parentheses needed around condition
- if is an expression — can assign to variables
- if let = concise for one pattern match + else
- let else = bind or early exit (modern favorite)
This + match covers 95% of control flow needs before loops.
Next ready?
- Loops (loop, while, for)?
- match expression (Rust’s superpower)?
- Or functions with if inside?
Just tell me — your Rust class is going strong! 🦀🚀
