If-Else Statements#
if condition {
// do something
}
if condition {
// do something
} else {
// do something else
}
if condition1 {
// do something
} else if condition2 {
// do something else
} else {
// fallback
}if as an Expression#
if is an expression in Rust and can return a value.
let x = if condition { 1 } else { 2 };
let message = if score >= 90 {
"Excellent"
} else if score >= 70 {
"Good"
} else {
"Needs improvement"
};if let#
if let matches a single pattern and is a concise alternative to match when only one case matters.
let some_value: Option<i32> = Some(42);
if let Some(n) = some_value {
println!("Got: {}", n);
} else {
println!("Got nothing");
}
// With enums
enum Status { Active, Inactive(String) }
let s = Status::Inactive(String::from("timeout"));
if let Status::Inactive(reason) = s {
println!("Inactive because: {}", reason);
}Match Statements#
match compares a value against a series of patterns and executes the matching arm. All arms must be exhaustive (cover all cases).
let number = 3;
match number {
1 => println!("one"),
2 | 3 => println!("two or three"), // OR pattern
4..=9 => println!("four to nine"), // range pattern
n if n < 0 => println!("negative: {}", n), // guard
_ => println!("something else"), // catch-all
}Match with Destructuring#
// Tuple destructuring
let pair = (0, -2);
match pair {
(0, y) => println!("on y-axis at {}", y),
(x, 0) => println!("on x-axis at {}", x),
(x, y) => println!("at ({}, {})", x, y),
}
// Struct destructuring
struct Point { x: i32, y: i32 }
let p = Point { x: 1, y: 0 };
match p {
Point { x, y: 0 } => println!("on x-axis at {}", x),
Point { x: 0, y } => println!("on y-axis at {}", y),
Point { x, y } => println!("at ({}, {})", x, y),
}
// Enum destructuring
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
Color(u8, u8, u8),
}
match msg {
Message::Quit => println!("quit"),
Message::Move { x, y } => println!("move to ({}, {})", x, y),
Message::Write(text) => println!("write: {}", text),
Message::Color(r, g, b) => println!("color: {}, {}, {}", r, g, b),
}Match as an Expression#
let description = match number {
1 => "one",
2 => "two",
_ => "other",
};Loops#
loop (infinite loop)#
Runs until an explicit break. Can return a value from break.
loop {
// do something
if condition {
break;
}
}
// loop with return value
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // returns 20
}
};while#
Runs as long as a condition is true.
let mut n = 0;
while n < 5 {
println!("{}", n);
n += 1;
}while let#
Continues looping while a pattern matches.
let mut stack = vec![1, 2, 3];
while let Some(top) = stack.pop() {
println!("{}", top); // prints 3, 2, 1
}for#
Iterates over anything that implements IntoIterator.
// Over a range
for i in 0..5 {
println!("{}", i); // 0, 1, 2, 3, 4
}
for i in 0..=5 {
println!("{}", i); // 0, 1, 2, 3, 4, 5
}
// Over a collection
let v = vec![10, 20, 30];
for item in &v {
println!("{}", item); // borrows items
}
// With index using enumerate
for (i, item) in v.iter().enumerate() {
println!("{}: {}", i, item);
}Loop Labels#
Loop labels allow break and continue to target outer loops.
'outer: for x in 0..5 {
for y in 0..5 {
if x == 2 && y == 2 {
break 'outer; // exits both loops
}
if y == 3 {
continue 'outer; // skip to next x
}
}
}continue and break#
for i in 0..10 {
if i % 2 == 0 {
continue; // skip even numbers
}
if i == 7 {
break; // stop at 7
}
println!("{}", i); // prints 1, 3, 5
}Troubleshooting#
| Issue | Cause | Solution |
|---|---|---|
non-exhaustive patterns in match | Not all enum variants or value ranges are covered | Add a catch-all _ arm or cover every variant explicitly |
if arms have incompatible types | Each branch of an if expression must return the same type | Ensure both branches evaluate to the same type, or use an enum/trait object |
irrefutable if let pattern warning | The pattern always matches (e.g. if let x = value) | Use a plain let binding instead of if let when the pattern cannot fail |
Infinite loop without break | Missing or unreachable break statement | Add a break with a reachable condition, or use while with a guard |
use of moved value inside a loop | Value is moved in the first iteration and unavailable afterward | Clone before using in the loop body, or borrow with & |