7.1 Conditional Statements: if
, else if
, else
Conditional statements allow code execution to depend on whether a condition is true or false. Rust uses if
, else if
, and else
, similar to C, but with important distinctions regarding type safety and usage as expressions.
7.1.1 Basic if
Statements
The structure of a basic if
statement is straightforward:
fn main() { let number = 5; // Parentheses around the condition are optional but allowed if number > 0 { println!("The number is positive."); } // Braces are always required, even for single statements }
Key Differences from C:
-
Strict Boolean Condition: The condition must evaluate to a
bool
type (true
orfalse
). Rust does not implicitly convert other types (like integers) to booleans.- C Example (Implicit Conversion):
int number = 5; if (number) { // Compiles in C: non-zero integer treated as true printf("Number is non-zero.\n"); }
- Rust Equivalent (Error):
You must write an explicit comparison, likefn main() { let number = 5; if number { // Compile-time error: expected `bool`, found integer println!("This won't compile"); } }
if number != 0
.
- C Example (Implicit Conversion):
-
Braces Required: Curly braces
{}
are mandatory for the code block associated withif
(andelse
/else if
), even if it contains only a single statement. This prevents ambiguity common in C where optional braces can lead to errors (like the “dangling else” problem or incorrect multi-statement blocks).
7.1.2 Handling Multiple Conditions: else if
and else
You can chain conditions using else if
and provide a default fallback using else
, just like in C:
fn main() { let number = 0; if number > 0 { println!("The number is positive."); } else if number < 0 { println!("The number is negative."); } else { println!("The number is zero."); } }
- Conditions are evaluated sequentially.
- The block associated with the first
true
condition is executed. - If no
if
orelse if
condition istrue
, theelse
block (if present) is executed.
7.1.3 if
as an Expression
Unlike C, where if
is only a statement, Rust’s if
can also be used as an expression, meaning it evaluates to a value. This is often used with let
bindings and eliminates the need for a separate ternary operator (?:
) like C has.
fn main() { let condition = true; let number = if condition { 10 // Value if condition is true } else { 20 // Value if condition is false }; // Semicolon for the `let` statement println!("The number is: {}", number); // Prints: The number is: 10 }
Important Requirement: When using if
as an expression, all branches (the if
block and any else if
or else
blocks) must evaluate to values of the same type. The compiler enforces this strictly.
fn main() { let condition = false; let value = if condition { 5 // This is an integer (i32) } else { "hello" // This is a string slice (&str) - Mismatched types! }; // Error: `if` and `else` have incompatible types }
If an if
expression is used without an else
block, and the condition is false, the expression implicitly evaluates to the “unit type” ()
. If the if
block does return a value, this leads to a type mismatch unless the if
block also returns ()
.
fn main() { let condition = false; // This `if` expression implicitly returns `()` if condition is false. let result = if condition { println!("Condition met"); // println! returns () }; // 'result' will have the type () println!("Result is: {:?}", result); // Prints: Result is: () }