What are Loops?
Loops allow you to execute a block of code repeatedly until a specified condition is met or indefinitely. In Rust, loops are powerful and efficient, ensuring memory safety and providing control over execution flow.
Types of Loops in Rust
a. The loop Keyword
The loop keyword creates an infinite loop that runs until explicitly stopped using the break statement.
Syntax:
loop {
// Code to execute
if condition {
break; // Exit the loop
}
}
Example: Simple Counter
fn main() {
let mut count = 0;
loop {
count += 1;
println!("Count is: {}", count);
if count == 5 {
break;
}
}
}
Output:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
b. The while Loop
The while loop executes as long as the given condition evaluates to true.
Syntax:
while condition {
// Code to execute
}
Example: Countdown Timer
fn main() {
let mut number = 5;
while number > 0 {
println!("Number: {}", number);
number -= 1;
}
println!("Liftoff!");
}
Output:
Number: 5
Number: 4
Number: 3
Number: 2
Number: 1
Liftoff!
c. The for Loop
The for loop iterates over a range, collection, or iterator. It is the most commonly used loop in Rust due to its simplicity and safety.
Syntax:
for variable in collection {
// Code to execute
}
Example: Iterating Over a Range
fn main() {
for number in 1..=5 {
println!("Number: {}", number);
}
}
Output:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Breaking and Continuing Loops
break Statement:
The break statement exits a loop prematurely.
Example:
fn main() {
for number in 1..=10 {
if number == 5 {
break; // Exit the loop when number equals 5
}
println!("Number: {}", number);
}
}
Output:
Number: 1
Number: 2
Number: 3
Number: 4
continue Statement:
The continue statement skips the rest of the loop body for the current iteration and moves to the next iteration.
Example:
fn main() {
for number in 1..=5 {
if number == 3 {
continue; // Skip number 3
}
println!("Number: {}", number);
}
}
Output:
Number: 1
Number: 2
Number: 4
Number: 5
Nested Loops
You can use loops inside other loops (nested loops). Rust allows you to label loops to control flow precisely.
Example: Multiplication Table
fn main() {
for i in 1..=3 {
for j in 1..=3 {
print!("{} ", i * j);
}
println!();
}
}
Output:
1 2 3
2 4 6
3 6 9
Using Labels with Loops:
Labels help identify specific loops in nested contexts.
fn main() {
'outer: for i in 1..=3 {
for j in 1..=3 {
if i == 2 && j == 2 {
break 'outer; // Breaks the outer loop
}
println!("i: {}, j: {}", i, j);
}
}
}
Output:
i: 1, j: 1
i: 1, j: 2
i: 1, j: 3
i: 2, j: 1
Infinite Loops and Early Exit
Infinite loops created with loop are useful for tasks like servers or real-time applications. Use break to exit based on conditions.
Example: Infinite Loop with Condition
fn main() {
let mut counter = 0;
loop {
counter += 1;
if counter == 10 {
break;
}
println!("Counter: {}", counter);
}
}
Using Loops with Collections
Loops are often used to iterate over collections like arrays, vectors, and hash maps.
Example: Iterating Over an Array
fn main() {
let numbers = [10, 20, 30, 40, 50];
for num in numbers {
println!("Number: {}", num);
}
}
Output:
Number: 10
Number: 20
Number: 30
Number: 40
Number: 50
Key Differences Between Loop Types
Type | Description | Use Case |
---|---|---|
loop | Runs indefinitely unless stopped | Real-time tasks, waiting processes |
while | Runs while a condition is true | Unknown number of iterations |
for | Iterates over a range or collection | Known number of iterations |