Loops are an essential part of any programming language, allowing repetitive execution of code until a condition is met.
Rust offers powerful and flexible loop constructs, including loop, while, and for.
Each type of loop is designed for specific scenarios, ensuring both performance and safety.
What You’ll Learn
- Types of Loops in Rust
- The loop Keyword
- The while Loop
- The for Loop
- Breaking and Continuing Loops
- Nested Loops
- Using Loops with Collections
- Practical Examples
1. Types of Loops in Rust
Rust provides three main looping constructs:
- loop: Infinite loop with manual exit.
- while: Conditional loop that runs while a condition is true.
- for: Iterates over a collection or range.
2. The loop Keyword
The loop keyword creates an infinite loop, which runs indefinitely until explicitly exited using break.
Example: Basic Infinite Loop
fn main() { let mut counter = 0; loop { println!("Counter: {}", counter); counter += 1; if counter == 5 { break; // Exit the loop when counter reaches 5 } } }
Example: Returning a Value from a Loop
You can return a value from a loop using break.
fn main() { let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; // Return double the counter when it reaches 10 } }; println!("Result: {}", result); }
3. The while Loop
The while loop runs as long as a specified condition evaluates to true.
Example: Basic while Loop
fn main() { let mut n = 1; while n <= 5 { println!("Number: {}", n); n += 1; } }
Example: Using while with a Condition
fn main() { let mut sum = 0; while sum < 20 { println!("Sum: {}", sum); sum += 3; } }
4. The for Loop
The for loop is commonly used for iterating over ranges, collections, or iterators.
Example: Iterating Over a Range
fn main() { for i in 1..5 { // Exclusive range: 1, 2, 3, 4 println!("i: {}", i); } for i in 1..=5 { // Inclusive range: 1, 2, 3, 4, 5 println!("i: {}", i); } }
Example: Iterating Over a Collection
fn main() { let names = ["Alice", "Bob", "Charlie"]; for name in names.iter() { println!("Name: {}", name); } }
5. Breaking and Continuing Loops
You can control the flow of loops using break and continue.
Example: Breaking a Loop
fn main() { for i in 1..10 { if i == 5 { break; // Exit the loop when i is 5 } println!("i: {}", i); } }
Example: Continuing to the Next Iteration
fn main() { for i in 1..10 { if i % 2 == 0 { continue; // Skip even numbers } println!("Odd number: {}", i); } }
6. Nested Loops
Rust supports loops inside loops, often used for iterating over multidimensional data.
Example: Nested for Loops
fn main() { for i in 1..=3 { for j in 1..=3 { println!("i: {}, j: {}", i, j); } } }
Example: Breaking Out of Nested Loops
Use labeled loops to exit a specific loop.
fn main() { 'outer: for i in 1..=3 { for j in 1..=3 { if i == 2 && j == 2 { break 'outer; // Exit the outer loop } println!("i: {}, j: {}", i, j); } } }
7. Using Loops with Collections
Rust loops are powerful for working with collections.
Example: Iterating Over a Vector
fn main() { let numbers = vec![10, 20, 30, 40]; for num in numbers.iter() { println!("Number: {}", num); } }
Example: Enumerating Indices and Values
fn main() { let fruits = vec!["Apple", "Banana", "Cherry"]; for (index, fruit) in fruits.iter().enumerate() { println!("Index: {}, Fruit: {}", index, fruit); } }
8. Practical Examples
8.1 Finding the Sum of a Range
fn main() { let sum: i32 = (1..=10).sum(); println!("Sum: {}", sum); }
8.2 Printing Multiplication Table
fn main() { for i in 1..=5 { for j in 1..=5 { print!("{:4}", i * j); } println!(); } }
8.3 Reversing a String
fn main() { let s = "Rust"; let reversed: String = s.chars().rev().collect(); println!("Reversed: {}", reversed); }
8.4 Finding Prime Numbers
fn is_prime(num: u32) -> bool { if num < 2 { return false; } for i in 2..=(num as f64).sqrt() as u32 { if num % i == 0 { return false; } } true } fn main() { for n in 2..50 { if is_prime(n) { println!("Prime: {}", n); } } }
8.5 Looping Until User Input Matches
use std::io; fn main() { let secret = "rustacean"; loop { println!("Guess the word:"); let mut guess = String::new(); io::stdin().read_line(&mut guess).unwrap(); let guess = guess.trim(); if guess == secret { println!("Correct!"); break; } else { println!("Try again."); } } }
9. Summary
Key Features
- loop: Infinite loop, exit with break.
- while: Conditional loop.
- for: Iterates over ranges, collections, or iterators.
- Control flow can be managed with break and continue.
Use Cases
- Infinite loops for event-driven programs.
- Conditional loops for dynamic termination.
- Iterating over collections like arrays, vectors, or ranges.