Elementary Overview
Control flow decides which code runs, how many times it runs, and when execution leaves a repeated block. Rust provides if expressions for decisions and three primary loop forms: loop, while, and for. Rust also makes several of these constructs expressions, so they can produce values rather than merely controlling execution.
This lesson follows OSRust.004: Functions, Parameters, Expressions, and Return Values. That lesson established Rust’s expression-oriented model. Control flow extends that model: an if block can produce a value, and a loop can return a value through break.
Learning Objectives
- Use
if,else if, andelse. - Explain why Rust requires an
ifcondition to evaluate tobool. - Use an
ifexpression to assign a value. - Create unconditional repetition with
loop. - Return a value from
loopusingbreak value. - Repeat while a Boolean condition is true with
while. - Iterate safely through collections and ranges with
for. - Skip an iteration with
continue. - Exit nested loops using labels.
- Choose the clearest loop form for a given problem.
if Is an Expression
Rust begins a conditional branch with if. The condition must evaluate to a Boolean value. Rust does not automatically reinterpret integers such as 0 or 1 as false or true, so comparisons must be explicit.
fn main() {
let temperature = 78;
if temperature > 85 {
println!("Cooling alert");
} else if temperature > 75 {
println!("Warm");
} else {
println!("Normal");
}
}
The first true branch runs and the remaining branches are skipped. Conditions can combine comparisons with Boolean operators such as &&, ||, and !.
Assigning a Value with if
Because if is an expression, its result can be assigned directly to a variable. Every branch that can produce the result must have a compatible type.
fn main() {
let online = true;
let status = if online {
"running"
} else {
"offline"
};
println!("{status}");
}
If one branch returned a string slice and the other returned an integer, the compiler would reject the assignment because one expression cannot have two incompatible result types. This builds directly on the type system introduced in OSRust.003: Scalar and Compound Data Types.
Unconditional Repetition with loop
The loop keyword repeats a block indefinitely until execution reaches a break, a function returns, the process exits, or another diverging operation occurs. It communicates intentional indefinite repetition more clearly than writing an artificial always-true condition.
fn main() {
let mut attempts = 0;
loop {
attempts += 1;
println!("Attempt {attempts}");
if attempts == 3 {
break;
}
}
}
Returning a Value from loop
Rust’s loop is an expression and can return a value. Supply that value after break, then assign the loop expression to a variable.
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("{result}");
}
This prints 20. The value after break becomes the value of the entire loop expression. That pattern is useful when repetition searches for, computes, or waits for a value before continuing.
Conditional Repetition with while
A while loop repeats only while its condition evaluates to true. It is appropriate when the number of iterations is not fixed in advance but the continuation condition is easy to state.
fn main() {
let mut countdown = 3;
while countdown != 0 {
println!("{countdown}!");
countdown -= 1;
}
println!("LIFTOFF");
}
Compared with manually combining loop, if, and break, while makes the controlling condition visible at the top of the loop.
Iterating with for
for is usually the clearest choice for traversing a collection or known range. It avoids manual indexing and lets Rust’s iterator system drive each iteration.
fn main() {
let temperatures = [68, 71, 74, 79];
for reading in temperatures {
println!("{reading} F");
}
}
This approach is safer and clearer than maintaining a separate integer index for a simple traversal. The loop receives each item from the collection in sequence.
Ranges
Ranges work naturally with for. The expression 1..5 produces 1 through 4, while 1..=5 includes 5.
fn main() {
for rack in 1..=5 {
println!("Checking rack {rack}");
}
for number in (1..=3).rev() {
println!("{number}!");
}
}
Skipping Work with continue
continue immediately ends the current iteration and returns control to the loop head. In a for loop, iteration proceeds to the next item.
fn main() {
for port in 1..=8 {
if port == 4 {
continue;
}
println!("Testing port {port}");
}
}
Port 4 is skipped, while the remaining ports continue normally. Use continue when the current item should be ignored without terminating the entire loop.
Breaking and Continuing Nested Loops with Labels
By default, break and continue affect the innermost enclosing loop. Rust lets you label loops with a leading apostrophe so nested control flow can target a specific outer loop.
fn main() {
‘rack_scan: for rack in 1..=3 {
for port in 1..=4 {
println!(“rack {rack}, port {port}”);
if rack == 2 && port == 3 {
break ‘rack_scan;
}
}
}
}
The labeled break exits the outer rack_scan loop immediately. A labeled continue can similarly skip directly to the next iteration of a selected outer loop.
Choosing the Right Loop
- Use
forwhen iterating through a collection, iterator, or known range. - Use
whilewhen repetition is governed by a Boolean condition. - Use
loopwhen repetition is intentionally open-ended and exit conditions occur inside the body. - Use
break valuewhen aloopis computing or searching for a value. - Use
continuewhen one iteration should be skipped but repetition should continue. - Use labels sparingly when nested loops require explicit control of an outer loop.
Mini Lab
- Create a project with
cargo new control_flow_lab. - Use an
ifexpression to classify a temperature as"normal","warm", or"hot". - Use
loopwithbreak valueto calculate a result after five iterations. - Create a countdown with
while. - Create an array of five device names and iterate through it with
for. - Use a range from 1 through 10 and skip even values with
continue. - Create nested rack-and-port loops and exit the outer loop with a label when a target rack and port are found.
- Run
cargo fmt,cargo check, andcargo run.
Knowledge Check
- What type must an
ifcondition evaluate to? - Can an
ifexpression produce a value? - What does
loopdo by default? - How can a
loopreturn a value? - When is
whileappropriate? - Why is
forusually preferable to manual indexing for simple collection traversal? - What does
continuedo? - Which loop does an unlabeled
breakexit? - What problem do loop labels solve?
Answers
bool.- Yes. All result-producing branches must have compatible types.
- It repeats indefinitely.
- Use
break valueand assign the loop expression. - When repetition should continue while a Boolean condition remains true.
- It expresses iteration directly and avoids unnecessary manual index management.
- It skips the remainder of the current iteration and starts the next one.
- The innermost enclosing loop.
- They let
breakorcontinuetarget a specific loop in nested control flow.
Previous Related Lessons
- OSRust.004: Functions, Parameters, Expressions, and Return Values
- OSRust.003: Scalar and Compound Data Types
- OSRust.002: Variables
Primary References
- The Rust Programming Language — Control Flow
- The Rust Reference — Loop Expressions
- Rust By Example — while
Elementary Conclusion
Rust control flow is structured around explicit Boolean decisions and expressive loops. Use if to choose a path, for to traverse data, while to repeat under a condition, and loop when exit logic belongs inside the body. Once break, continue, values, ranges, and labels are understood, these constructs become the foundation for larger Rust programs.
BitcoinVersus.Tech Editor’s Note:
We volunteer daily to ensure the credibility of the information on this platform is Verifiably True. If you would like to support to help further secure the integrity of our research initiatives, please donate using the QR code provided

For best QR-code scanning results, please scan this donation code from a desktop or larger screen. Mobile screens may prevent camera recognition.

Leave a Reply